首先来看这样一个 ts 例子bash
import { Button, ButtonProps } from './components/button'
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type BigButtonProps = Omit<ButtonProps, 'size'>
function BigButton(props: BigButtonProps) {
return Button({ ...props, size: 'big' })
}
复制代码
若是对这个例子很清晰,大佬请点击右上角。post
若是不清楚 咱们能够来往下共同探索一番。。ui
partial, Readonly, Record, Pickspa
Partial 做用是将传入的属性变为可选项.code
keyof, incomponent
首先咱们须要理解两个关键字
keyof
和in
,keyof
能够用来取得一个对象接口的全部key
值.cdn好比对象
interface Foo {
name: string;
age: number
}
// T -> "name" | "age"
type T = keyof Foo
type Keys = "a" | "b"
type Obj = {
[p in Keys]: any
}
// Obj -> { a: any, b: any }
复制代码
keyof
产生联合类型, in
则能够遍历枚举类型, 因此他们常常一块儿使用, 看下 Partial 源码blog
type Partial<T> = { [P in keyof T]?: T[P] };
复制代码
使用接口
interface Foo {
name: string;
age: number;
}
type B = Partial<Foo>;
// 最多只可以定义 name, age 中的属性(能够不定义)
let b: B = {
name: '1',
age: 3,
};
复制代码
Required 的做用是将传入的属性变为必选项, 源码以下
type Required<T> = { [P in keyof T]-?: T[P] };
复制代码
咱们发现一个有意思的用法 -?
, 这里很好理解就是将可选项表明的 ?
去掉, 从而让这个类型变成必选项. 与之对应的还有个+?
, 这个含义天然与-?
以前相反, 它是用来把属性变成可选项的.
从 T 中取出 一系列 K 的属性
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
复制代码
总结一下 Partial, Required, Pick。
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Required<T> = {
[P in keyof T]-?: T[P];
};
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface User {
age: number;
name: string;
};
// 至关于: type PartialUser = { age?: number; name?: string; }
type PartialUser = Partial<User>
// 至关于: type PickUser = { age: number; name: string; }
type PickUser = Pick<User, "age" | "name">
复制代码
在 ts 2.8 中引入了一个条件类型, 示例以下
T extends U ? X : Y
复制代码
以上语句的意思就是 若是 T 是 U 的子类型的话,那么就会返回 X,不然返回 Y
type Exclude<T, U> = T extends U ? never : T;
const str: Exclude<'a' | '1' | '2', 'a' | 'y' | 'z'> = '1';
复制代码
从代码 str 的提示,能够很好的理解,Exclude 就是将前面类型的与后面类型对比,过滤出前面独有的属性
经过使用 Pick 和 Exclude 来组合一个新的类型 Omit
// Pick
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
// Exclude
type Exclude<T, U> = T extends U ? never : T;
// Omit
type Omit = Pick<T, Exclude<keyof T, K>>
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
interface User {
id: number;
age: number;
name: string;
}
// 至关于: type OmitUser = { age: number; name: string; }
type OmitUser = Omit<User, 'id'>;
复制代码
很好理解,去除掉 User 接口内的 id 属性。
回过头看以前的代码
import { Button, ButtonProps } from './components/button'
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type BigButtonProps = Omit<ButtonProps, 'size'>
function BigButton(props: BigButtonProps) {
return Button({ ...props, size: 'big' })
}
复制代码
首先定义了一个 BigButtonProps 类型, 这个类型经过 Omit 除去了 size 属性。解决!!
全文章,若有错误或不严谨的地方,请务必给予指正,谢谢!
参考: ts高级技巧