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); // Ok
f(1, 'a'); // Error
f('a', 2); // Error
f('a', 'b') // Ok
function f(a: string, b: string): string
function f(a: number, b: number): number
function 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>>>