筆記。
- 交叉類型
- 聯合類型
- 類型保護
- null和undefined
- 類型保護和類型斷言
- 類型別名
- 字面量類型
- 枚舉成員類型
- 可辨識聯合
// 交叉類型 & const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => { // 返回值類型是多種 let res = {} as T & U res = Object.assign(arg1, arg2) return res } console.log(mergeFunc({ a: 'a', b: 'b'}, { b: '1', c: 'c'})) // {a: 'a', b: '1', c: 'c'} // 聯合類型 type1 | type2 | type3 const getLengthFunc = (content: string | number): number => { if (typeof content === 'string') { return content.length } else { return content.toString().length } } console.log(getLengthFunc('abcd')) // 4 console.log(getLengthFunc(22312)) // 5 // 類型保護 const valueList = [123, 'abc'] const getRandomValue = () => { const num = Math.random() * 10 if (num < 5) { return valueList[0] } else { return valueList[1] } } const item = getRandomValue() // 隨機的值 不知道哪種類型 // 1.自定義類型保護(一般用於複雜的判斷,這種簡單的建議用下面幾種) function isString(value: number | string): value is string { return typeof value === 'string' } // if (item.length) { console.log(item.length) } 因類型不確定報錯 // else { console.log(tiem.toFixed(2)) } if (isString(item)) { console.log(item.length) } else { console.log(item.toFixed(2)) } // 2.typeof 類型保護 string/number/boolean/symbol 四種之一 if (typeof item === 'string') { console.log(item.length) } else { console.log(item.toFixed(2)) } // 3.instanceof 類型保護 class CreateByClass1 { public age = 18 } class CreateByClass2 { public name = 'van' } function getRandomItem() { return Math.random() < 0.5 ? new CreateByClass1() : new CreateByClass2() } const item1 = getRandomItem() if (item1 instanceof CreateByClass1) { console.log(item1.age) } else { console.log(item1.name) } // null和undefined 任何類型的子類型 let values = '123' // values = undefined // 配置文件 strictNullChecks // string | undefined / string | null / string | undefined | null 三者不同 const sumFunc = (x: number, y?: number) => { return x + (y || 0) } // 類型保護和類型斷言 ! const getLengthFunction = (value: string | null): number => { // if (value == null) { return 0 } // else { return value.length } 簡寫如下 return (value || '').length } function getSpliceStr(num: number | null): string { function getRes(prefix: string) { return prefix + num!.toFixed().toString() } num = num || 0.1 return getRes('van-') } console.log(getSpliceStr(1.782)) // 類型別名 type type TypeString = string let str2: TypeString type PositionType<T> = { x: T, y: T } const position1: PositionType<number> = { x: 1, y: -1 } const position2: PositionType<string> = { x: '3.22215', y: '1.23421' } type Childs<T> = { current: T, child?: Childs<T> } let ccc: Childs<string> = { current: 'first', child: { current: 'second', child: { current: 'third' } } } type Alias = { num: number } interface Inter { // implements 擴展的時候用interface num: number } let _alias: Alias = { num: 123 } let _interface: Inter = { num: 321 } _alias = _interface // 類型別名和接口 兼容 // 字面量類型 // 1. 字符串字面量(具體的string) type Name = 'van' // const name1: Name = 'v' 報錯 type Direction = 'north' | 'west' | 'south' | 'east' function getDirectionFirstLetter(direction: Direction) { return direction.substr(0, 1) } console.log(getDirectionFirstLetter('east')) // 2. 數字字面量(具體的number) type Age = 18 interface InfoInterface { name: string age: Age } const _info: InfoInterface = { name: 'van', age: 18 // age: 3 // 必須是18 不然報錯 } // 枚舉成員類型 // 可辨識聯合 // 兩要素:1.具有普通的單例類型屬性 2.一個類型別名包含了哪些類型的聯合 interface Square { kind: 'square' size: number } interface Rectangle { kind: 'tangle' height: number width: number } interface Circle { kind: 'circle' radius: number } type Shape = Square | Rectangle | Circle // 聯合類型 function assertNever(value: never): never { throw new Error('Unexpected object: '+ value) } function getArea(s: Shape): number { switch(s.kind) { case 'square': return s.size * s.size; break; case 'tangle': return s.height * s.width; break; case 'circle': return Math.PI * s.radius ** 2; break; default: return assertNever(s); } } // 完整性檢查 // 1. 配置文件 strictNullChecks: true // 2. 使用never類型
學得慢 不重要。書看的慢 不重要。