使用泛型类型检查承诺时typescript的奇怪行为

使用泛型类型检查承诺时typescript的奇怪行为,typescript,promise,Typescript,Promise,我试图让编译器检查承诺的类型,但我得到了一个奇怪的行为。下面是我尝试过的4个不同的return选项: interface MyResponse<T> { foo: number, data: T, } const g: () => Promise<MyResponse<number>> = async () => { // This behavior is fine, the compiler complains, as expec

我试图让编译器检查承诺的类型,但我得到了一个奇怪的行为。下面是我尝试过的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'
  }

}
接口MyResponse{
傅:号码,
数据:T,
}
常量g:()=>Promise=async()=>{
//编译器抱怨说,正如预期的那样,这种行为很好:
//错误:“字符串”类型不能分配给“数字”类型。
返回{
傅:1,,
数据:“错误类型”
}
//foo和数据都丢失了,但我没有发现错误。我不知道为什么
返回{}
//数据丢失,但仍然没有错误
返回{
傅:1
}
//现在编译器抱怨“数据”丢失了
//错误:类型“{foo:number;bar:string;}”中缺少属性“data”。
返回{
傅:1,,
酒吧:“这失败了”
}
}
值得注意的是,如果我不使用
Promise
(也不使用
async
),那么我会得到预期的错误

知道为什么会这样吗

[编辑]:这与应使用typescript 2.4修复的typescript错误有关(请参阅)


@nitzan tomer的答案在下一版本之前仍然是一个很好的解决办法。

当您稍微更改函数的签名时,这个问题似乎得到了解决:

const g = async (): Promise<MyResponse<number>> => {
    ...
}
const g=async():Promise=>{
...
}
使用您的原始签名,会发生以下情况:

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

const g2: () => Promise<MyResponse<number>> = g1
const g1=async()=>{
返回{}
}
常数g2:()=>Promise=g1
g1
的类型是
()=>Promise
,编译器认为可以将此类型分配到
()=>Promise

它仅在返回值的结构与
MyResponse
的结构冲突时才会发出抱怨


编辑 从版本2.4开始,此问题已修复。
原版:。
与:.

修复于:。

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

const g = async (): Promise<MyResponse<number>> => {
    ...
}
const g=async():Promise=>{
...
}
使用您的原始签名,会发生以下情况:

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

const g2: () => Promise<MyResponse<number>> = g1
const g1=async()=>{
返回{}
}
常数g2:()=>Promise=g1
g1
的类型是
()=>Promise
,编译器认为可以将此类型分配到
()=>Promise

它仅在返回值的结构与
MyResponse
的结构冲突时才会发出抱怨


编辑 从版本2.4开始,此问题已修复。
原版:。
与:.

修正:。

第一个选项不合适。您正在生成MyResponse,这意味着数据属性是一个数字,但您正在尝试在其中设置一个字符串。这就是它抱怨的原因。好的是编译器抱怨,正如预期的那样:)第一个选项不好。您正在生成MyResponse,这意味着数据属性是一个数字,但您正在尝试在其中设置一个字符串。这就是它抱怨的原因。好的是编译器抱怨,正如预期的:)尽管这里仍然有一个问题,我看到你为它打开了一个问题:是的,这在我看来仍然有点可疑。特别是最后一条错误消息很奇怪。我真的希望我没有弄错,但在我看来,这里还有改进的余地。尽管如此,这里仍然存在一个问题,我看到你为此提出了一个问题:是的,这在我看来仍然有点可疑。特别是最后一条错误消息很奇怪。我真的希望我没有弄错,但在我看来这里还有改进的余地。