Skip to content
On this page

TS Notes

Type VS Interface

Primitive Types

typescript
type Name = string;

Array

Type

typescript
type Names = string[]
type Names = Array<string>

Interface

typescript
interface Names {
  [index: number]: string;
}

Tuples

typescript
type Point = [number, number]

WARNING

後續仍可以做 push 的動作,TS 不會出現警告。

Function

Type

typescript
type Log = (message: string) => void

Interface

typescript
interface Log {
  (message: string): void;
}

Union Types

typescript
type Status = "pending" | "working" | "complete"

Objects

Type

typescript
type Person = {
  name: string;
  score: number;
}

Interface

typescript
interface Person {
  name: string;
  score: number;
}

Composing Objects

Type

typescript
type Name = {
  firstName: string;
  lastName: string;
}

type PhoneNumber = {
  landline: string;
  mobile: string;
}

type Contact = Name & PhoneNumber

WARNING

interface 也可以被組進 type

Interface

typescript
interface Name {
  firstName: string;
  lastName: string;
}

interface PhoneNumber {
  landline: string;
  mobile: string;
}

interface Contact extends Name, PhoneNumber {}

Authoring a Library

typescript
interface ButtonProps {
  text: string;
  onClick: () => void ;
}

interface ButtonProps {
  id: string;
}

TIP

重複名稱會造成 ButtonProps 的結果型別組合在一起:

typescript
interface ButtonProps {
  text: string;
  onClick: () => void;
  id: string;
}

DANGER

type 不允許相同名稱。

implements

Class 會用 implements 指定要實作的 Interface ,一旦指定了就得把 Interface 內所有的 MethodProperty 給實作。
而 Class 還是可以寫下 Interface 內沒有描述到的 MethodProperty,因為 Interface 只是約束了最低需要哪些行為而已。

typescript
interface TheCar {
  name: string;
  move(): void;
}

class Car implements TheCar {
  name: string

  constructor(name: string) {
    this.name = name
  }

  move(): void {
    console.log('開始加速')
  }
}

而且,一個 Class 也能夠同時被多個 Interface 給約束,每個 Interface 間使用逗號間隔。

typescript
class Car implements TheCarA, TheCarB {
  ...
}

⋯ Reference

Type Guard

  • typeof:用於 primitive type
  • instanceof:用於 class
  • in:用於 object(檢查 object 是否有此屬性)
  • propertyName in objectVariable;:回傳 truefalse
  • extends:限制泛型可被代入的型別(generic constraints)或是作為型別的條件判斷(conditional types)

    假設現在我們希望限制這個 T 只能是數值(number)的話,可以搭配 extends 寫成 <T extends number>,意思就是限制使用者帶入的泛型。
    T 需要是 number 的子集合

    typescript
    function getFirstElement<T>(arr: T[]): T {
      const [firstElement] = arr;
      return firstElement;
    }

    更精確的來說,應該是指「 T 要是 number 的子集合(subset)」。

extends 擴展某一個 interfaces

typescript
interface A extends B {
  firstName: string;
  lastName: string;
}

⋯ Reference

Conditional Types

  • infer:必須使用在「條件類型的子句」,也就是 extends 後面、? 前面的位置。
ts
type Item<T> = T extends (infer U)[] ? U : never;

⋯ Reference

Immutable

方法編輯階段執行階段限制對象
readonly警告仍可執行寫在誰前面就限制誰
Readonly<T>警告仍可執行只限制最外層
Object.freeze()警告不可執行只限制最外層
as const警告不可執行從外到內每層都限制

Function Overloads

(函式超載)
擴充一個函式可以被執行的形式。
針對同一個 function 提供多個不同的 type definition。
可以使用相同的 function 名稱,定義不同的參數數量或型別創建多種方法。

包含兩個部分:

  • overload signatures

    type definition 的部分,通常會定義 2 種或以上。

  • function implementation

    實際上執行的 function,它的型別需要滿足所有的 overload signatures。

範例:

typescript
function padding(all: number): object
function padding(topAndBottom: number, leftAndRight: number): object
function padding(top: number, right: number, bottom: number, left: number): object

// implementation
function padding(a: number, b?: number, c?: number, d?: number) {
  /* ... */
}

注意

  1. 要至少 2 個或以上的 overload signatures
  2. implementation function 帶入的參數型別要兼容 overload signatures 的型別

⋯ Reference