TypeScript 中的可等待类型

问题描述 投票:0回答:3

我在 JavaScript 中经常使用 async/await。现在我正在逐渐将代码库的某些部分转换为 TypeScript。

在某些情况下,我的函数接受将被调用并等待的函数。这意味着它可以返回一个承诺,只是一个同步值。我为此定义了

Awaitable
类型。

type Awaitable<T> = T | Promise<T>;

async function increment(getNumber: () => Awaitable<number>): Promise<number> {
  const num = await getNumber();
  return num + 1;
}

可以这样调用:

// logs 43
increment(() => 42).then(result => {console.log(result)})

// logs 43
increment(() => Promise.resolve(42)).then(result => {console.log(result)})

这有效。然而,必须为我所有使用 async/await 和 TypeScript 的项目指定

Awaitable
是很烦人的。

我真的不敢相信这样的类型不是内置的,但我找不到。 TypeScript 有内置的可等待类型吗?

typescript async-await
3个回答
5
投票

我相信这个问题的答案是:不,没有内置类型。

lib.es5.d.ts
lib.es2015.promise.d.ts
中,他们在
T | PromiseLike<T>
有意义的各个地方使用
Awaitable<T>
,例如:

/**
 * Represents the completion of an asynchronous operation
 */
interface Promise<T> {
    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;

    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}

Awaitable
中,没有什么比你的
lib.es5.d.ts
更好的了,他们定义了
PromiseLike
Promise

我认为如果他们定义了一个,他们会在这些定义中使用它。

旁注:根据这些定义,在

PromiseLike
中使用
Promise
而不是
Awaitable
可能是有意义的:

type Awaitable<T> = T | PromiseLike<T>;

0
投票

作为 T.J. Crowder 指出,最好使用

PromiseLike(T) | T
。使用
PromiseLike
而不是
Promise
允许对象符合 Promise 接口,而不是内置
Promise
类型的实例。

确实没有内置的实用程序类型,但 ts-essentials 提供了

AsyncOrSync
类型,定义如下:

type AsyncOrSync<Type> = PromiseLike<Type> | Type;

在你的函数中,你可以像这样使用它:

import type { AsyncOrSync } from "ts-essentials";

async function increment(getNumber: () => AsyncOrSync<number>): Promise<number> {
  const num = await getNumber();
  return num + 1;
}

-1
投票
  1. async/await
    总是会导致语句被包装到 Promise 中,因此你的函数将始终返回一个 Promise。
  2. 一切都可以等待,无论它是否异步,因此自定义
    Awaitable
    类型可能只是多余的......
async function test() {
    const foo = await 5;
    console.log(foo);

    const bar = await 'Hello World';
    console.log(bar);

    const foobar = await Promise.resolve('really async');
    console.log(foobar);
}

test();

ts游乐场链接

恕我直言,您不需要额外输入,因为您的函数将始终具有:

async function foo<T>(task: () => T | Promise<T>): Promise<T> {
  const result = await task();

  return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.