2.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