TypeScript 中的?infer
?关键字用于在类型推断上下文中捕获泛型中的类型。它主要用于在定义条件类型或者创建复杂的类型映射时,从已知类型中派生出未知类型。
以下是一个简单的使用?infer
?的案例:
Typescript
// 定义一个可以提取数组元素类型的工具类型
type ExtractArrayElementType<T> = T extends readonly any[] ? T[number] : never;
// 使用infer改进上述类型,以更明确地表达我们的意图(提取数组元素类型)
type ExtractArrayType<T> = T extends readonly (infer U)[] ? U : never;
// 示例用法:
type StringArrayElement = ExtractArrayType<string[]>; // 结果为 string
type NumberArrayElement = ExtractArrayType<number[]>; // 结果为 number
// 更复杂的例子:从联合类型中提取所有对象类型的共有属性
type CommonProperties<T> = T extends object ?
{ [K in keyof T]: infer U }[keyof T] :
never;
type ObjA = { a: string, b: number };
type ObjB = { a: string, c: boolean };
type SharedProps = CommonProperties<ObjA & ObjB>; // 结果为 string
在这个例子中,infer U
?在?ExtractArrayType
?类型中被用来表示数组元素的具体类型,并且通过类型守卫检查和条件类型来提取出来。
另一个例子是提取函数返回类型:
Typescript
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function myFunction(): { result: string } {
return { result: "Hello" };
}
type MyFunctionReturnType = ReturnType<typeof myFunction>; // 结果为 { result: string }
这里?infer R
?被用来捕获?T
?所代表的函数的返回类型。
是的,使用 TypeScript 中的 `infer` 关键字可以用于推断 Promise 的返回类型,这样在处理异步函数时,你通常不需要手动指定 Promise 的 resolve 值的具体类型。例如:
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
// 示例用法:
async function fetchUser(id: string): Promise<{ id: string, name: string }> {
? // 假设这是从服务器获取用户数据的异步操作
}
let userPromise: Promise<{ id: string, name: string }> = fetchUser('123');
// 使用 infer 推断 Promise 的结果类型
type UserType = UnwrapPromise<ReturnType<typeof fetchUser>>; // 结果为 { id: string, name: string }
// 现在我们可以直接使用推断出的类型而无需显式声明
const resolvedUser: UserType = await fetchUser('456');
在这个例子中,`UnwrapPromise` 类型定义了一个条件类型,它检查传入的 `T` 是否是一个 Promise,并通过 `infer` 来提取 Promise 中包含的实际类型 `U`。因此,当我们应用这个类型到一个返回 Promise 的函数上时,它可以自动地帮助我们得到 Promise 解决后的具体类型。