【问题标题】:Does TypeScript not ensure a Promise is resolved with the correct type?TypeScript 是否不能确保使用正确的类型解析 Promise?
【发布时间】:2017-06-04 13:07:56
【问题描述】:

这在 TypeScript 2.1.5 中编译没有错误:

function promiseANumber(): Promise<number> {
    return new Promise(resolve => resolve('definitely not a number'));
}

我希望会报告一个错误,因为根据类型定义,解析函数是用字符串而不是数字调用的。

为什么 TypeScript 的编译器没有捕获和报告这种类型不匹配?


编辑 1

再看一下,改用异步函数定义,编译器会正确报告类型不匹配。所以这个:

async function promiseANumber(): Promise<number> {
    return 'definitely not a number';
}

给予

error TS2322: Type '"definitely not a number"' is not assignable to type 'number'.

为什么这些案例表现不同?


编辑 2

这看起来像是让编译器正确捕获它以明确告诉它您要返回的承诺类型的方法。所以这就足够了:

function promiseANumber() {
    return new Promise<number>(resolve => resolve('definitely not a number'));
}

编译器现在抱怨的:

error TS2345: Argument of type '"definitely not a number"' is not assignable to parameter of type 'number | Thenable<number>'.

我想我现在的问题是,考虑到我在这个问题开头给出的定义,为什么编译器不能推断这一点?


编辑 3

令人高兴的是,TypeScript 2.4 现在为我的原始代码指出了正确的错误!这是因为它现在支持return types as inference targets。该公告甚至有一个与我最初给出的示例非常相似的代码示例。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    在这种情况下...

    function promiseANumber(): Promise<number> {
        return new Promise(resolve => resolve('definitely not a number'));
    }
    

    ...resolve 不期望number 的原因是因为它在编写new Promise(...) 时被指定为{},因为这是new Promise() 的默认类型。然后编译器允许将Promise&lt;{}&gt; 赋值给Promise&lt;number&gt;... 这本身就是有问题的。

    在这种情况下...

    async function promiseANumber(): Promise<number> {
        // type returned is Promise<string>, doesn't match Promise<number>
        return 'definitely not a number';
    }
    

    ...返回的类型是Promise&lt;string&gt;,与Promise&lt;number&gt; 不匹配,因此编译器会抛出错误。


    在您的承诺示例中,您可以告诉编译器将承诺定义为Promise&lt;number&gt;,方法是:

    function promiseANumber(): Promise<number> {
        return new Promise<number>(resolve => resolve('definitely not a number'));
    }
    

    ...这将导致编译错误,因为string 不能分配给number

    【讨论】:

    • 在您的第一个示例中,您可以显式编写类型,即const myPromise: Promise&lt;number&gt; = ...。这相当于我在我的问题中的第一个例子。但这似乎仍然对编译器没有帮助。为什么?
    • 我明白了,谢谢。遗憾的是,编译器没有根据周围函数的签名推断返回的 promise 是 Promise。出于某种原因,这在技术上是不可能的,还是只是 TypeScript 的当前限制?
    猜你喜欢
    • 2017-05-31
    • 2018-06-04
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2012-08-05
    • 2023-01-27
    相关资源
    最近更新 更多