typescript 中的 infer 关键字的理解
infer
infer 是在 typescript 2.8
中新增的关键字。
infer
可以在 extends
条件类型的字句中,在真实分支中引用此推断类型变量,推断待推断的类型。
例如:用infer
推断函数的返回值类型
type ReturnType = T extends (...args: any[]) => infer R ? R : any;
type fn = () => number
type fnReturnType = ReturnType // number
在这个例子中,
T extends U ? X : Y
的形式为条件类型。infer R
代表待推断的返回值类型,如果 T
是一个函数(...args: any[]) => infer R
,则返回函数的返回值 R
,否则返回any
案例:加深理解
反解 Promise
// promise 响应类型
type PromiseResType = T extends Promise ? 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 // Promise
// 反解
type StrPromiseRes = PromiseResType // strtype PersonPromise = ReturnType // Promise// 反解
type PersonPromiseRes = PromiseResType【typescript 中的 infer 关键字的理解】 // Person
反解函数入参类型
type Fn = (...args: A) => any
type FnArgs = T extends Fn ? A : anyfunction strFn (name: string) {}type StrFn = FnArgs // [string]
tuple 转 union ,如:[string, number] -> string | number
type ElementOf = T extends Array ? E : nevertype TTuple = [string, number];
type ToUnion = ElementOf;
// string | number
new 操作符
// 获取参数类型
type ConstructorParameters any> = T extends new (...args: infer P) => any ? P : never;
// 获取实例类型
type InstanceType any> = T extends new (...args: any[]) => infer R ? R : any;
class TestClass {constructor(
public name: string,
public string: number
) {}
}type Params = ConstructorParameters;
// [string, numbder]type Instance = InstanceType;
// TestClass
react - reducer
// 定义
function useReducer(
reducer: R,
// ReducerState 推断类型
initializerArg: I & ReducerState,
initializer: (arg: I & ReducerState) => ReducerState
): [ReducerState, Dispatch>];
// infer推断
type ReducerState = R extends Reducer
? S
: never;
// Reducer类型
type Reducer = (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 {
[isRefSymbol]: true
value: T
}export function ref(value: T): T extends Ref ? T : Ref>export type UnwrapRef = {
cRef: T extends ComputedRef ? UnwrapRef : T
ref: T extends Ref ? UnwrapRef : T
array: T
object: { [K in keyof T]: UnwrapRef }
}[T extends ComputedRef
? 'cRef'
: T extends Array
? '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) // Refconst count = ref(ref(2)) // Ref
参考
- 理解TypeScript中的infer关键字
- Vue3 跟着尤雨溪学 TypeScript 之 Ref 类型从零实现
- 巧用 TypeScript(五)---- infer
推荐阅读
- 热闹中的孤独
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- Android中的AES加密-下
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- 如何在Mac中的文件选择框中打开系统隐藏文件夹