Skip to main content

各種 Type 機制

  • primitive type TS 中型別有兩種:primitive typeobject type 其中 primitive type (原始型別) 有:boolean、number、string、null、undefined 和 ES6 的 Symbol
    • 宣告方式

      let a: boolean = false;
      let b: number = 98;
      let c: string = "test";
      let d: string = `${c}123`; // 嵌入變數
      let e: undefined = undefined;
      let f: null = null;

      console.log(a);
      console.log(b);
      console.log(c);
      console.log(d);
      console.log(e);
      console.log(f);
    • 不回傳用 void

      function test(num: number): void {
      console.log(num);
      }

      test(87);
  • Union
    • 宣告方式用 | 來分隔型別

      // 可以是 string or number 型別
      let a: string | number

      a = 'test'
      console.log(a)

      a = 87
      console.log(a)
    • 用在 function,只能使用共同的方法、屬性 toString() 是 number、string 共同的方法,所以可以使用;如果改成 length 會報錯

      function getString(something: number | string): string {
      return something.toString()
      }

      console.log(getString(98))

      console.log(getString('test'))
    • union type 的變數被 assign 時,會根據型別推論的規則推斷出當下型別

      let something: string | number

      // 目前是 string
      something = 'test'
      console.log(something.length)

      // 目前是 number
      something = 98
      console.log(something.length) // 會報錯
  • Pick (從一個型別中取出子集當成一個型別)
    • 可以增加閱讀性

      type Info = {
      name: string;
      age: number;
      account: string;
      password: string;
      phoneNumber: string;
      };

      // 從 Info 裡面取出 password,phoneNumber 成為一個新的 type
      type Secret = Pick<Info, "password" | "phoneNumber">;

      const secret: Secret = {
      password: "password",
      phoneNumber: "0987654321",
      };
  • Record
    • 將兩個 type 組成一個分別是 key,value 的新 type

      type CatName = 'A' | 'B' | 'C'

      type CatInfo = {
      age: number
      breed: string
      }

      // Record<CatName, CatInfo> 是一個物件
      // key 是 CatName,value 是 CatInfo
      const cats: Record<CatName, CatInfo> = {
      A: { age: 5, breed: 'AAA' },
      B: { age: 10, breed: 'BBB' },
      C: { age: 15, breed: 'CCC' }
      }
  • Partial / Required
    • Partial: 屬性都變成 option

    • Required: 屬性都變成必須

      type Student = {
      name?: string
      age: number
      }
      type PartialStudent = Partial<Student>
      type RequiredStudent = Required<Student>

      const student: Student = { age: 20 }
      const partialStudent: PartialStudent = {}
      const requiredStudent: RequiredStudent = { name: 'Sam', age: 27 }
  • Intersection type &
    • 對 object type 會取聯集

      type Identity = {
      id: string
      name: string
      }

      type Contact = {
      phone: string
      email: string
      }

      type Employee = Identity & Contact

      const employee: Employee = {
      id: 'A001',
      name: 'Tom',
      phone: '0123456789',
      email: 'abc@gmail.com'
      }
    • 對 union type 會取交集

      type A = string | number
      type B = string | boolean

      // 會是交集
      type C = A & B // string
  • Any & Unknown 相同地方:
    • 都可以接受任意型別

      不同地方:

    • any 可以 assign 給任何型別

    • unknown 只能 assign 給 any or unknown

    • any 可以任意操作屬性 or 方法

    • unknown 要執行型別斷言型別檢查才能操作屬性 or 方法且通過編譯

      Any

    • any 可以被 assign 任意型別

      // any 可以被 assign 任意型別
      let a: any = "test";
      console.log(a);

      a = 87;
      console.log(a);

      a = true;
      console.log(a);
    • 宣告時不指定型別,就會是 any

      // 等同於 let something: any;
      let something;

      something = true;
      console.log(something);

      something = 98;
      console.log(something);
    • any 的問題

      let a: any = 19;

      let str: string = a;

      // 編譯時期沒事,但執行時期會錯
      console.log(str.toLowerCase());

      Unknown

    • 只能 assign 給 unknown or any

      let a: unknown = 19;

      // assign 給 unknown & any
      let b: unknown = a;
      let c: any = a;

      // 會報錯!!
      let str: string = a;
    • 沒有推斷是什麼型別之前,禁止操作屬性與方法

      let a: unknown = "123";

      if (typeof a === "string") {
      console.log(a.toUpperCase()); // 推斷後可以用方法
      }
  • Never 用途:
    1. 無窮迴圈

      function infiniteLoop(num: number): never {
      while (true) {
      console.log(num)
      }
      }
    2. throw exception

      function generateError(message: string): never {
      throw new Error(message)
      }
  • Omit (忽略特定屬性)
    type Todo = {
    title: string
    description: string
    completed: boolean
    createdAt: number
    }

    type TodoPreview = Omit<Todo, 'description' | 'createdAt'>

    const todo: TodoPreview = {
    title: 'Finish recap 2021',
    completed: false
    }