【问题标题】:Typescript function/callback Type: no error when assigning function with "wrong" return value打字稿函数/回调类型:分配具有“错误”返回值的函数时没有错误
【发布时间】:2020-03-11 10:54:23
【问题描述】:

在下面的代码中,我将函数 doSomething 的类型定义为这种类型:(value: User) => User

奇怪的是,当将返回类型错误的函数分配给 doSomething 时,Typescript 不会抱怨。这是为什么?

interface User {
    userName: string;
}

const test: User = {
    userName: 'test',
    bla: '123' // OK:  TS complains
}

let doSomething: (value: User) => User;

doSomething = () => { // NOK: TS is not complaining about the missing parameter
  return {
    userName: 'test',
    bla: '123' // NOK: Why does TS not complain?
  }
};

在定义回调函数的类型然后传递返回“错误”值的回调时也会发生同样的情况:

interface User {
    userName: string;
}

class Test {
    doSomething(callback: (value: User) => User): void {}
}

const test = new Test();

test.doSomething(() => { // NOK: TS is not complaining about the missing parameter
  return {
    userName: 'test',
    bla: '123' // NOK: Why does TS not complain?
  }
})

查看 stackblitz 上的示例:https://stackblitz.com/edit/typescript-callback-2

【问题讨论】:

  • Typescript 不会对对象文字以外的任何内容进行过多的属性检查,这是设计使然。
  • Nice JS forEach 示例:forEach(callback: (element?: T, index?: number, array?: T[])) 这说明跳过参数非常好。

标签: typescript


【解决方案1】:

您可以安全地使用具有 less 参数的回调,然后是定义的类型,但没有不同或更多:

test.doSomething(() => {...}                  // allowed
test.doSomething((user) => {...}              // allowed
test.doSomething((user1, user2) => {...}      // error
test.doSomething((username:string) => {...}   // error

通过这种方式,您可以提供一个可能不需要调用它的所有值的回调。

然后您可以安全地向返回的对象添加更多属性,但您不能跳过强制属性或更改它们的类型:

return { userName: 'test', bla: '123'}   // ok, just an extra parameter
return { }                               // not ok, userName is required
return { userName: 42}                   // not ok, userName is required to be a string

没关系,因为结果的接收者可以忽略所有额外的属性,不会造成任何伤害。

【讨论】:

  • 我知道跳过参数很好。因为我们不必将所有参数传递给例如`Array.forEach(callback: (element?: T, index?: number, array?: T[]))` 但是与标准类方法相比,允许附加道具的回调的返回类型感觉有点不一致:stackblitz.com/edit/typescript-callback-2-pwydkg
猜你喜欢
  • 2015-06-12
  • 1970-01-01
  • 2017-11-25
  • 2020-05-27
  • 1970-01-01
  • 2018-11-01
  • 2020-11-25
  • 2022-01-12
相关资源
最近更新 更多