使用泛型类型检查promise时,typescript的奇怪行为

时间:2017-05-09 15:34:53

标签: typescript promise

我正在尝试让编译器检查一个promise的类型,但是我得到了一个奇怪的行为。以下是我尝试的4种不同的return选项:

interface MyResponse<T> {
  foo: number,
  data: T,
}

const g: () => Promise<MyResponse<number>> = async () => {

  // This behavior is fine, the compiler complains, as expected:
  // ERROR: Type 'string' is not assignable to type 'number'.
  return {
    foo: 1,
    data: 'wrong type'
  }

  // Both foo and data are missing, but I get no error. I don't get why
  return {}

  // data is missing, but still no error
  return {
    foo: 1
  }

  // Now the compiler complains about `data` being missing
  // ERROR: Property 'data' is missing in type '{ foo: number; bar: string;  }'.
  return {
    foo: 1,
    bar: 'this fails'
  }

}

值得注意的是,如果我不使用Promise(也不是async),那么我会收到预期的错误。

知道为什么会这样吗?

[编辑]:这与应该用typescript 2.4修复的打字稿错误有关(见discussion on github

@ nitzan-tomer的答案仍然是一个很好的解决方法,直到下一个版本。

1 个答案:

答案 0 :(得分:5)

当您稍微更改函数的签名时,似乎已解决此问题:

const g = async (): Promise<MyResponse<number>> => {
    ...
}

使用原始签名会发生这种情况:

const g1 = async () => {
    return {}
}

const g2: () => Promise<MyResponse<number>> = g1

g1的类型为() => Promise<{}>,编译器认为可以将此类型分配到() => Promise<MyResponse<number>>

只有在返回值的结构与MyResponse的结构冲突时才会抱怨。

修改

自版本2.4起,此问题已得到解决 原始问题:Weird checking errors when using async function, and generic typings
相关:Generic parameter inference for Promise.then oddity
已修复:Covariant checking for callback parameters