3.2K
原文地址:https://medium.com/@lucas.paganini/typescript-infer-keyword-40d42148dd84
本文我们将介绍 TypeScript 的 infer关键字。这个关键字用于从泛型导出类型。下面以Promise为例:
type UnpackPromise<P> = ✨magic✨ UnpackPromise<Promise<string>> // <- string UnpackPromise<Promise<number>> // <- number UnpackPromise<Promise<boolean>> // <- boolean
我们要实现的是一个UnpackPromise类型。这个类型可以返回Promise泛型的实际类型。如果P是关于T的Promise的子类型,我们希望UnpackPromise返回T;否则,返回never,表示不会有这样的类型。于是,我们想用这样的语句来实现:
type UnpackPromise<P> = P extends Promise<T> ? T : never;
但这并不能正常运行,因为T并不存在。
为了描述清楚,我们来看看函数是如何实现的:
const UnpackPromise = (P) => P === Promise<T> ? T : never
P是一个参数,但T是哪来的?
作为一个正常的函数,你可以创建一个名叫T的变量,例如:
const UnpackPromise = (P) => P === Promise<var T> ? T : never
这就是infer关键字的来源。它看起来就像是某种类型变量的声明。
type UnpackPromise<P> = P extends Promise<infer T> ? T : never;
如果P是Promise的子集,我们需要告诉 TypeScript 去推断Promise的内部类型,并且把这个类型保存为T,然后返回这个T。
type UnpackPromise<P> = P extends Promise<infer T> ? T : never; UnpackPromise<Promise<string>> // <- string UnpackPromise<Promise<number>> // <- number UnpackPromise<Promise<boolean>> // <- boolean UnpackPromise<Promise<Array<Date>>> // <- Array<Date> UnpackPromise<Promise<boolean | string>> // <- boolean | string