iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Modern Web

如何用TypeScript水30天鐵人賽系列 第 12

[Day12]:鴨子的形狀 - interface介面 Part 1

  • 分享至 

  • xImage
  •  

Day12 Banner

恩~ 鴨子就是長這樣... 嗎?

鵝 、 鵝 、 鵝
曲項向天歌,白毛浮綠水
紅掌撥清波...
等等? 這是鴨子?
────────────────────── By 駱賓王


目標:Interface(介面)

物件導向的語言中,Interface(介面)(也稱接口)是一個很重要的概念,
它是對行為的一種抽象,如何運作則由Class(類別)Implement(實現)

而在TypeScript 中的Interface(介面)是一個非常靈活的概念,
除了可用於對Class(類別)的部分行為進行抽象以外,
也很常用描述Object(物件)Shape(形狀)


過程:

  • 1. Object face

    上一節中筆記了各種Object(物件)的type法,
    其實更常使用得方式是透過Interface(介面)來定義:

     interface iMember {
       title: string;
       age: number;
       gender: 'man' | 'woman' | 'other';
       car?: null | string;  // 和funciton 一樣 加了? 就是可選參數
       house?: undefined | string; //
       summary(): void;
     }
    
     let Opshell: iMember = {
       title: 'Opshell',
       age: 30,
       gender: 'man',
       summary: function () { return `${this.title}:${this.age} years old, is a ${this.gender}.`; }
     }
    
     console.log(member.summary()); // Opshell:30 years old, is a man.
    

    ※ 在使用上,一般習慣在前面加上大寫的I,並使用PascalCase(帕斯卡)命名法。
    當然沒有硬性規定,還是看個人或團隊風格,Ops習慣加小寫i並使用(lowerCamelCase(小駝峰式)命名法。
    Interface(介面)描述物件的Shape(形狀),有甚麼好處呢?
    這樣我們就可以反覆使用,例如我今天要多一個成員:

     let Bear: iMember = {
       title: 'Bear',
       age: 40,
       gender: 'man',
       summary: function () { return `${this.title} is the bearer of the Maya Zoo, he is ${this.age} years old.`; }
     }
    

    是不是覺得 Object 的宣告方便了不少。


  • 2. Array face

    宣告 Array 的Shape(形狀)當然也是很容易的:

     interface iTeamArray {
       [index: number]: string;
     }
    
     let maya: iTeamArray = [ 'Opshell', 'Bear', 'Patty', 'Egg' ];
    

    在javascript 中 Array(陣列) 其實也是種物件,
    所以我們宣告 key 名 為 index 會是 number 類別,
    value 是字串類型。


  • 3. any object face

    透過上面例子的原理,我們可以推論出:

     interface iDictionary {
       [propName: string]: any;
     }
    

    這樣就會變成,可以接受任何型別的物件face。


  • 4. function face

    Object(物件)Array(陣列)當然也會有Function(函式)
    在 [Day10] - function part 2 有稍微提到,
    現在我們來更深入的了解 function face:

     type tGender = 'man' | 'woman' | 'other';
    
     interface iMemberSummary {
       (title: string, age: number, gender: tGender): void;
     }
    
     // 如果用 type alias(別名) 來定義型別會長這樣
     type tMemberSummary = (title: string, age: number, gender: tGender) => string;
    
     // 這個 greet function 會自動符合 Greet 這個 interface
     let memberSummary: iMemberSummary = (title, age, gender) => {
       return `${title}:${age} years old, is a ${gender}.`;
     };
    
     console.log(memberSummary('Opshell', 30, 'man')); // Opshell:30 years old, is a man.
    
     // 參數名稱不符合,只要型別符合即可 Interface 的形狀。
     // 例如這裡改用 n, a, g 當作參數名稱,一樣符合 iMemberSummary
     let memberSummary2: iMemberSummary = (n: string, a: number, g: tGender) => {
       return `${title}:${age} years old, is a ${gender}.`;
     };
    
     console.log(memberSummary('Opshell', 30, 'man')); // Opshell:30 years old, is a man.
    

    會發現從前面的篇章到這邊,
    Ops一直在偷渡type alias(別名)的使用方式,
    其實是因為type alias(別名)的使用上和Interface(介面)極度接近,
    先讓各位熟悉一下,之後在比較的時候,就會更容易搞懂。


  • 5. Hybrid face

除了一般屬性外,也可以混Function(函式)進來,
所以上面的例子可以改成這樣:

 type tGender = 'man' | 'woman' | 'other';

 interface iMember {
   (title: string, age: number, gender: tGender): string; // 要輸入的參數
   title: string; // 物件Key
   age: number; // 物件Key
   gender: tGender; // 物件Key
   summary(): string; // 物件 function
 }

 const getMember = (): iMember => {
   let member = function (title: string, age: number, gender: tGender) {
      member.title = title;
      member.age = age;
      member.gender = gender;
   } as iMember;

   member.summary = () => {
      return `${member.title}:${member.age} years old, is a ${member.gender}.`;
   };

   return member;
 };

 // Opshell 同時是物件,也是函式
 const Opshell = getMember();
 Opshell('Opsehll', 30, 'man');
 console.log(Opshell.title); // Opsehll
 console.log(Opshell.summary()); // Opsehll:30 years old, is a man.

混合模式比較複雜,可能要多看幾次才會懂,
需要實際操作才比較理解,之後有機會在示範其他範例。


小結:

學習了基本的 JavaScript 三物件的 Interface(介面)
內容有點多,可能會看得霧煞煞,
尤其是混合模式,實在是很容易搞混阿,
不過如果把javascript裡的一切都是物件的概念帶進來,
就會清楚很多,就先寫到這邊,
明天再把剩下的Interface(介面)寫完。
大家明天見~


上一篇
[Day11]:這是一隻鴨子 - Object
下一篇
[Day13]:鴨子的行為 - interface介面 Part 2
系列文
如何用TypeScript水30天鐵人賽33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言