TypeScript 中简单但损坏的三元条件表达式

Simple but broken ternary conditional expression in TypeScript

TypeScript 2.7 让我可以这样做:

const promise = Promise.resolve();
promise.then(() => {});

它让我可以这样做:

const promise = new Promise(() => {});
promise.then(() => {});

那么为什么我不能这样做呢?

const promise = true
  ? Promise.resolve()
  : new Promise(() => {});

promise.then(() => {});

此示例在官方 TypeScript PlayGround 上也无法正常运行:

http://www.typescriptlang.org/play/index.html#src=const%20promise%20%3D%20true%0D%0A%20%20%3F%20Promise.resolve()%0D%0A%20%20%3A%20new%20Promise(()%20%3D%3E%20%7B%7D)%3B%0D%0A%0D%0Apromise.then(()%20%3D%3E%20%7B%7D)%3B

编译错误如下:

Cannot invoke an expression whose type lacks a call signature. Type '(<TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResul...' has no compatible call signatures.

我可以通过将 promise 的类型从 Promise<void> | Promise<{}> 指定为 Promise<void | {}> 来 "fix" 错误:

const promise: Promise<void | {}> = true
  ? Promise.resolve()
  : new Promise(() => {});

promise.then(() => {});

为什么?

因为你承诺的类型是:

const promise: Promise<void> | Promise<{}>

例如改为:

const promise = true
  ? Promise.resolve()
  : new Promise<void>(() => {}); // Note the explicit generic type parameter.

promise.then(() => {});

这可能是由于可分配性问题,例如:

let x: (a: void) => void = () => { };
let y: (a: {}) => void = () => { };

y = x; // Type '(a: void) => void' is not assignable to type '(a: {}) => void'.
x = y; // Type '(a: {}) => void' is not assignable to type '() => void'.