【问题标题】:Why does TypeScript not throw a compilation error for this promise chain?为什么 TypeScript 不会为这个 Promise 链抛出编译错误?
【发布时间】:2016-12-21 16:49:44
【问题描述】:

我仍在学习 Typescript,所以也许我只是从根本上遗漏了一些东西,但我不明白为什么以下代码会引发编译错误:

// An example without Promises (does not compile)
function getAnObject(): Object {
  return { value: 'Hello' };
};

function doSomethingWithAString(input: String) {
  console.log(input);
}

const result = getAnObject();
// error TS2345: Argument of type 'Object' is not assignable to parameter of type 'String' 
doSomethingWithAString(result);

但下面的代码没有:

// A similar example with Promises (compiles)
function getAnObjectAsync(): Promise<Object> {
  return Promise.resolve({ value: 'Hello' });
};

getAnObjectAsync().then(function (result: String) {
// Throws a runtime exception
console.log(result.toUpperCase());
});

为什么 TypeScript 没有抱怨 Promise 示例中 .then 的 onfulfilled 函数会收到 result: Object?

  • 我做错了吗?
  • 我对这个例子有什么不明白的地方吗?

【问题讨论】:

    标签: javascript typescript promise


    【解决方案1】:

    这是因为在 TS 中,函数参数的类型是双变量的。

    在 Promise.then 的情况下,只要其参数是所需类型的子类型或超类型,任何传递的函数都将被接受。所以一个对象 (Object, {}) 将始终被接受。幸运的是,它仍然可以捕捉到广泛不兼容的类型。就像期待 { x: string} 但收到 { y: number } 这样它会捕获大多数类型错误。

    这是一个有利有弊的设计决策; (我个人认为不值得)他们甚至可能在未来改变它,因为最后几个版本的 TS 显然是朝着让 TS 越来越健全的方向发展。

    【讨论】:

    • 什么是使函数双变量的优点?
    • 我也不相信 :) 但他们写了这个:github.com/Microsoft/TypeScript/wiki/… 你无法定义自己的方差并且可以在 JS 中改变事物的事实无济于事
    • 感谢您的链接。我不同意这个结论,认为他们的论点有缺陷,但至少他们有一个:-)
    • 更新:TS 2.4 现在有适当的逆变函数参数!
    猜你喜欢
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多