在最新版本的 TypeScript 4.5 中,有一个名为Awaited的新类型。看起来这种类型是用于处理承诺的。我发现文档中对此没有很好的描述,并且我在任何地方都没有找到任何更好的示例。
有人可以解释一下这种类型的用途及其工作原理吗?
先感谢您。
jca*_*alz 14
如果您正在寻找实用程序类型的Awaited<T>
更详细和解释性文档,您可能需要查看TypeScript 4.5 发行说明的相关部分以及实施拉取请求microsoft/TypeScript#45350。
的目标是描述函数中Awaited<T>
表示的(也许令人惊讶的)复杂类型操作。当你输入某种类型的值时,你将得到一个类型的值:await
async
await
T
Awaited<T>
async function foo<T>(x: T) {
const y = await x;
// const y: Awaited<T> in TS4.5 and above
// (just T in TS4.4 and below)
}
Run Code Online (Sandbox Code Playgroud)
T
如果您正在使用的类型await
不是Promise
任何类型,则Awaited<T>
与以下内容相同T
:
async function bar(x: string) {
const y = await x;
// const y: string
// Awaited<string> is just string
}
Run Code Online (Sandbox Code Playgroud)
T
如果您正在查找的类型await
是 a ,Promise<U>
其中U
不是Promise
任何类型,则Awaited<T>
与 相同U
:
async function baz(x: Promise<string>) {
const y = await x;
// const y: string
// Awaited<Promise<string>> is just string
}
Run Code Online (Sandbox Code Playgroud)
T
当您输入的类型await
是 a时,事情会变得更加复杂Promise<Promise<V>>
;如果V
不是 a Promise
,则Awaited<T>
与 相同V
:
async function qux(x: Promise<Promise<string>>) {
const y = await x;
// const y: string
}
Run Code Online (Sandbox Code Playgroud)
这是因为await
递归地解开任何Promise
s ,直到遇到非Promise
(或一些可怕的错误条件,例如具有方法的非承诺对象then()
);你永远不应该Promise
从以下内容中得到 a await
:
async function quux(x: Promise<Promise<Promise<Promise<string>>>>) {
const y = await x;
// const y: string
}
Run Code Online (Sandbox Code Playgroud)
因此,这Awaited<T>
也意味着通过以下递归条件类型递归地解开 Promise :
/**
* Recursively unwraps the "awaited type" of a type.
Non-promise "thenables" should resolve to `never`.
This emulates the behavior of `await`.
*/
type Awaited<T> =
T extends null | undefined ? T : // special case for `null | undefined`
// when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ?
// `await` only unwraps object types with a callable `then`.
// Non-object types are not unwrapped
F extends ((value: infer V, ...args: infer _) => any) ?
// if the argument to `then` is callable, extracts the first argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T; // non-object or non-thenable
Run Code Online (Sandbox Code Playgroud)
它还处理联合类型;例如,如果你有一个东西是a或astring
和Promise<number>
it await
,那么你将得到a或string
a:number
async function union(x: string | Promise<number>) {
const y = await x;
// const y: string | number
}
Run Code Online (Sandbox Code Playgroud)
递归包装的联合依此类推:
async function wha(x: number | Promise<string | Promise<number | Promise<Promise<boolean>>>>) {
const y = await x;
// const y: string | number | boolean
}
Run Code Online (Sandbox Code Playgroud)
在 TypeScript 4.5 之前,上面的await
方法大部分都可以工作,但是存在一些问题,特别是在Promise
-combination 方法的行为方面,例如Promise.all()
:
async function oops(x1: Promise<string | Promise<number>>, x2: Promise<string | Promise<number>>) {
const y = await Promise.all([x1, x2]);
// const y: [string | Promise<number>, string | Promise<number>] in TS4.4 and below
// const y: [string | number, string | number] in TS4.5 and above
}
Run Code Online (Sandbox Code Playgroud)
因此,引入该Awaited<T>
类型是为了更全面地处理Promise
操作的影响,面对人们报告为错误的一些奇怪的边缘情况(您可以在 microsoft/TypeScript#45350 中看到)。
在实践中,您可能不需要自己过多处理它,但它的存在很有帮助。
Eve*_*ert 11
简短的版本是给定的Awaited<X>
,您将得到:
X - If X was not a promise,
Y - If X was Promise<Y>
Z - If X had the type Promise<Promise<Z>>
Run Code Online (Sandbox Code Playgroud)
所以:
Awaited<number> -> Gives you number
Awaited<Promise<string>> -> Gives you string
Awaited<Promise<Promise<boolean>>> -> Gives you boolean
Run Code Online (Sandbox Code Playgroud)
这个想法是,在 Javascript 中,你可以等待非承诺并返回相同的值:
const x = await 5; // x = 5
Run Code Online (Sandbox Code Playgroud)
上面的例子在Awaited
引入之前就已经有些可能了,但是当 Promise 类型像 一样嵌套时,就会变得很奇怪Promise<Promise<Y>>
,所以 tl;dr 是:
类型Awaited<X>
是当你await
使用 type 的东西时你得到的X
。换句话说,它会删除任意数量的Promise
包装。(或者更具体地说,PromiseLike
)。
归档时间: |
|
查看次数: |
7956 次 |
最近记录: |