深入理解typescript中的infer關鍵字的使用
infer 這個關鍵字,整理記錄一下,避免後面忘記瞭。有點難以理解呢。
infer
infer 是在 typescript 2.8中新增的關鍵字。
infer 可以在 extends 條件類型的字句中,在真實分支中引用此推斷類型變量,推斷待推斷的類型。
例如:用infer推斷函數的返回值類型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; type fn = () => number type fnReturnType = ReturnType<fn> // number
在這個例子中,
T extends U ? X : Y的形式為條件類型。
infer R代表待推斷的返回值類型,如果T是一個函數(…args: any[]) => infer R,則返回函數的返回值R,否則返回any
案例:加深理解
反解 Promise
// promise 響應類型 type PromiseResType<T> = T extends Promise<infer R> ? R : T // 驗證 async function strPromise() { return 'string promise' } interface Person { name: string; age: number; } async function personPromise() { return { name: 'p', age: 12 } as Person } type StrPromise = ReturnType<typeof strPromise> // Promise<string> // 反解 type StrPromiseRes = PromiseResType<StrPromise> // str type PersonPromise = ReturnType<typeof personPromise> // Promise<Person> // 反解 type PersonPromiseRes = PromiseResType<PersonPromise> // Person
反解函數入參類型
type Fn<A extends any[]> = (...args: A) => any type FnArgs<T> = T extends Fn<infer A> ? A : any function strFn (name: string) { } type StrFn = FnArgs<typeof strFn> // [string]
tuple 轉 union ,如:[string, number] -> string | number
type ElementOf<T> = T extends Array<infer E> ? E : never type TTuple = [string, number]; type ToUnion = ElementOf<ATuple>; // string | number
new 操作符
// 獲取參數類型 type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never; // 獲取實例類型 type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any; class TestClass { constructor( public name: string, public string: number ) {} } type Params = ConstructorParameters<typeof TestClass>; // [string, numbder] type Instance = InstanceType<typeof TestClass>; // TestClass
react – reducer
// 定義 function useReducer<R extends Reducer<any, any>, I>( reducer: R, // ReducerState 推斷類型 initializerArg: I & ReducerState<R>, initializer: (arg: I & ReducerState<R>) => ReducerState<R> ): [ReducerState<R>, Dispatch<ReducerAction<R>>]; // infer推斷 type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never; // Reducer類型 type Reducer<S, A> = (prevState: S, action: A) => S; // 使用 reducer const reducer = (x: number) => x + 1; const [state, dispatch] = useReducer(reducer, ''); // Argument of type "" is not assignable to parameter of type 'number'.
vue3 – ref
export interface Ref<T = any> { [isRefSymbol]: true value: T } export function ref<T>(value: T): T extends Ref ? T : Ref<UnwrapRef<T>> export type UnwrapRef<T> = { cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T ref: T extends Ref<infer V> ? UnwrapRef<V> : T array: T object: { [K in keyof T]: UnwrapRef<T[K]> } }[T extends ComputedRef<any> ? 'cRef' : T extends Array<any> ? 'array' : T extends Ref | Function | CollectionTypes | BaseTypes ? 'ref' // bail out on types that shouldn't be unwrapped : T extends object ? 'object' : 'ref'] // 使用 const count = ref({ foo: ref('1'), bar: ref(2) }) // 推斷出 const count: Ref<{ foo: string; bar: number; }> const count = ref(2) // Ref<number> const count = ref(ref(2)) // Ref<number>
參考
理解TypeScript中的infer關鍵字
Vue3 跟著尤雨溪學 TypeScript 之 Ref 類型從零實現
巧用 TypeScript(五)—- infer
到此這篇關於深入理解typescript中的infer關鍵字的使用的文章就介紹到這瞭,更多相關typescript infer關鍵字內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- TypeScript中條件類型精讀與實踐記錄
- 你可能不知道的typescript實用小技巧
- 關於C++ TpeScript系列的泛型
- 在 TypeScript 中使用泛型的方法
- 淺談typescript中keyof與typeof操作符用法