1对extends的理解
type User = { id: number; kind: string;};function makeCustomer<T extends User>(u: T): T { return { id: u.id, kind: 'customer' }} // Error(TS 编译器版本:v4.4.2) // Type '{ id: number; kind: string; }' is not assignable to type 'T'. // '{ id: number; kind: string; }' is assignable to the constraint of type 'T', // but 'T' could be instantiated with a different subtype of constraint 'User'.
type User = { id: number; kind: string;};function makeCustomer<T extends User>(u: T): T { return { ... u, id: u.id, kind: 'customer' } 或者 return Object.assign(u, { id: u.id, kind: 'customer' })}T extends User T的属性可能比User更多,直接返回User格式的类型是不行的,这样会导致丢失其他属性
2函数重载
function f(a: string | number, b: string | number) { if (typeof a === 'string') { return a + ':' + b; // no error but b can be number! } else { return a + b; // error as b can be number | string }}f(2, 3); // Okf(1, 'a'); // Errorf('a', 2); // Errorf('a', 'b') // Ok
function f(a: string, b: string): stringfunction f(a: number, b: number): numberfunction f(a: CustomType, b: CustomType): CustomType { if (typeof a === 'string' || typeof b === 'string') { return `${a}:${b}` } return a + b}先是定义两种情况,然后在实现里通过typeof判断值的类型,对不同情况来做不同处理
3把指定类型变成可选
type Foo = { a: number; b?: string; c: boolean;}// 测试用例type SomeOptional = SetOptional<Foo, 'a' | 'b'>;// type SomeOptional = {// a?: number; // 该属性已变成可选的// b?: string; // 保持不变// c: boolean; // }
type Foo = { a: string, b: number, c: boolean}// Simplify 数组扁平处理(确保类型属性是来自T类型的属性)type Simplify<T> = { [P in keyof T]: T[P]}0. 这里的T就是上面定义的Foo类型,K是Foo类型的属性1. Pick<T,K> 从T中挑选出K属性2. Partial<T> 把T中的所有属性变为可选3. keyof T 获取T类型的所有属性4. Exclude<T,K> 从T类型中删除掉K中所有属性5. Pick<T,K> 从T类型中挑出剩下的类型6. & 前面一部分跳出了要设置的属性,并把它们都设置成了可选,然后通过&加上没有选择的属性,保持这些属性原来的类型7. Simplify<T> 代码提示会更友好,直接显示Foo的改变type SetOptional<T, K extends keyof T> = Simplify<Partial<Pick<T, K>> & Pick<T,Exclude<keyof T, K>>>
3.2把指定类型变成必需
type Foo = { a: string, b: number, c: boolean}type Simplify<T> = { [P in keyof T]: T[P]}type SetRequired<T, K extends keyof T> = Simplify<Required<Pick<T,K>> & Pick<T, Exclude<keyof T, K>>>