Skip to content
    在 Opshell 的 Blog 中:
  • 目前已分享 70 篇文章
  • 還有 114 個坑正在填補中
  • 已有: Loading 次觀看
  • 已有: Loading 個人來過
✍️ Opshell
📆 Last Updated:8/23/2024Created:2022/09/12
👀 已被閱讀: Loading

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

Day12 Banner

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

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


目標:Interface(介面)

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

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


過程:

  • 1. Object face

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

    typescript
     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(形狀),有甚麼好處呢? 這樣我們就可以反覆使用,例如我今天要多一個成員:

    typescript
     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(形狀)當然也是很容易的:

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

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


  • 3. any object face

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

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

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


  • 4. function face

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

    typescript
     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(函式)進來, 所以上面的例子可以改成這樣:

typescript
 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(介面)寫完。 大家明天見~

Released under the MIT License.