typescript不推断promise.all()推断类型

发布于 2025-02-10 07:09:40 字数 544 浏览 1 评论 0原文

请向某人解释该ts的原因和机制与a> string vs 'test')的类型与<代码> B 同时。我该如何解决?游乐场为在这里。先感谢您。

(async () => {
    const [a]: ['test'] = await Promise.all([Promise.resolve('test')])
    //     ^ type mismatch here
    const b: 'test' = await Promise.resolve('test')
    console.log(a, b)
})()

Please explain someone the reason and mechanics of that TS doesn't match the types for a (string vs 'test') matching those for b at the same time. How can I solve this? The playground is here. Thank you in advance.

(async () => {
    const [a]: ['test'] = await Promise.all([Promise.resolve('test')])
    //     ^ type mismatch here
    const b: 'test' = await Promise.resolve('test')
    console.log(a, b)
})()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吝吻 2025-02-17 07:09:40

这里的问题似乎是实现Promise.resolve()函数。任何实施打字的人都不希望将类型推断出尽可能狭窄。

const c = await Promise.resolve("test")
//    ^? c: string

如您所见,当调用Promise.resolve()使用字符串字面的字体时,该类型被宽扩大到string

有趣的是,在给变量的显式类型时,这不会发生。

const d: "test" = await Promise.resolve("test")
//    ^? d: "test"

这种行为似乎在版本3.5上发生了变化,但我仍在寻找解释此功能的变形值。


那么您有什么选择?

  1. 当使用Promise.resolve()时,请使用作为const
const [a1] = await Promise.all([Promise.resolve('test' as const)])
//     ^? a1: "test"
  1. 您可以为Promise.resolve()编写自己的包装功能,该功能尊重狭窄类型。
type Every =
  | null
  | string
  | number
  | boolean
  | Array<Every>
  | object
  | symbol
  | undefined
  | {
      [prop: string]: Every
    }

function PromiseResolve<T extends Every>(p: T): Promise<T> {
  return Promise.resolve(p)
}


const [a2] = await Promise.all([PromiseResolve('test')])
//     ^? a2: "test"

Playground

The issue here seems to be the implementation of the Promise.resolve() function. Whoever implemented the typing did not want types to be inferred as narrow as they could be.

const c = await Promise.resolve("test")
//    ^? c: string

As you can see, when calling Promise.resolve() with a string literal, the type is widened to string.

Interestingly, this does not happen when giving an explicit type to the variable.

const d: "test" = await Promise.resolve("test")
//    ^? d: "test"

This behaviour seemed to change in version 3.5 but I am still looking for the changelog which explains this feature.


So what are your options?

  1. Use as const when using Promise.resolve().
const [a1] = await Promise.all([Promise.resolve('test' as const)])
//     ^? a1: "test"
  1. You could write your own wrapper function for Promise.resolve() which respects narrow types.
type Every =
  | null
  | string
  | number
  | boolean
  | Array<Every>
  | object
  | symbol
  | undefined
  | {
      [prop: string]: Every
    }

function PromiseResolve<T extends Every>(p: T): Promise<T> {
  return Promise.resolve(p)
}


const [a2] = await Promise.all([PromiseResolve('test')])
//     ^? a2: "test"

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文