首先來看這樣一個 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高級技巧