# Composing Types ###### tags: `Javascript, React, Typescript` ref: https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html#composing-types ## Unions unions 的使用情境像是下方的字串或是字串的形式 ```typescript= type WindowStates = "open" | "closed" | "minimized"; type LockStates = "locked" | "unlocked"; type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9; ``` 或是使用在 function 中的參數,可以帶入字串或是字串陣列 ```typescript= function getLength(obj: string | string[]) { return obj.length; } ``` 甚至可以透過 typeof 來判斷參數的型別決定之後的動作 ```typescript= function wrapInArray(obj: string | string[]) { if (typeof obj === "string") { return [obj]; (parameter) obj: string } return obj; } ``` ## Generics ref: https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html#generics Generics 提供 types 變數做操作,從下方範例可以看到是一個 <> 包裹做為變數,讓 Array 型別有更多的延伸操作 ```typescript= type StringArray = Array<string>; type NumberArray = Array<number>; type ObjectWithNameArray = Array<{ name: string }>; ``` 下方範例可以看到,Type 的部分就是這邊的 Generics 並且全部帶入 string ```typescript= interface Backpack<Type> { add: (obj: Type) => void; get: () => Type; } // This line is a shortcut to tell TypeScript there is a // constant called `backpack`, and to not worry about where it came from. declare const backpack: Backpack<string>; //這邊把 Type 帶入 string // object is a string, because we declared it above as the variable part of Backpack. const object = backpack.get(); // Since the backpack variable is a string, you can't pass a number to the add function. backpack.add(23); Argument of type 'number' is not assignable to parameter of type 'string'. ``` ## Structural Type System 又稱作 duck typing 因為可以省略一些 type 的撰寫,當兩個物件有同樣的 value type 時,就會被視為同一個 type 因此可以忽略不寫 ```typescript= interface Point { x: number; y: number; } function logPoint(p: Point) { console.log(`${p.x}, ${p.y}`); } // logs "12, 26" const point = { x: 12, y: 26 }; logPoint(point); ``` 甚至只有有 子集 有符合,多一點屬性也可以被接受,但如果完全對不上則不符合 ```typescript= const point3 = { x: 12, y: 26, z: 89 }; logPoint(point3); // logs "12, 26" const rect = { x: 33, y: 3, width: 30, height: 80 }; // x, y 有符合即可被接受 logPoint(rect); // logs "33, 3" const color = { hex: "#187ABF" }; // 屬性對不上 logPoint(color); Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'. Type '{ hex: string; }' is missing the following properties from type 'Point': x, y ``` 只要其屬性是一樣的,在 class 上的行為也是一樣可以被接受 ```typescript= class VirtualPoint { x: number; y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } } const newVPoint = new VirtualPoint(13, 56); logPoint(newVPoint); // logs "13, 56" ```