繁体   English   中英

Typescript 回调类型检查

[英]Typescript type check on callback

最近开始学习Typescript,遇到了这个概念上看不懂的问题。 给这个function定义参数类型有错吗?

setTimeout((a: string) => {
    console.log(a); // ==> Prints 5 as a number
}, 1, 5);

为什么调用回调时不进行类型检查?

我将如何 go 关于使 typescript 引发错误?

遇到这样的事情时,我的一般解决方案是什么?

这是 TypeScript 中的一个已知错误,请参阅microsoft/TypeScript#32186 setTimeout()的类型看起来像

setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;

它接受任何参数列表,而不关心类型。 TimerHandler定义

type TimerHandler = string | Function

它使用不安全和无类型的Function类型 因此,不幸的是, setTimeout()在 TypeScript 中的输入非常松散。 通常在这种情况下,您可以使用声明合并来添加更好的调用签名,但在这种情况下,没有什么可以阻止编译器回退到不安全的调用签名。

这似乎只是 TS 中的一个限制。 该问题被列为“积压”,因此不会很快得到解决。 您可以将 go 发送给 microsoft/TypeScript#32186 并给它一个并显示对它的修复的支持,但它不太可能发生太大变化。

目前只有解决方法。


可以决定使用您自己lib.dom.ts的本地副本,您可以在其中修改safeTimeout()的定义,但维护起来会非常烦人。

您可以使用的一种解决方法是将setTimeout包装在您自己的 function 中,它的类型更强,然后只使用它可能是这样的:

const safeSetTimeout: <A extends any[]>(
    handler: (...args: A) => void, timeout?: number, ...args: A
) => number = setTimeout;

这使用generics来强类型化handler回调所期望的args与传递给setTimeout()本身的args相同。 让我们看看它的工作原理:

safeSetTimeout((a: string) => {
    console.log(a);
}, 1, 5); // <-- error!  number is not assignable to string
//    ~

太好了,我们在5上得到了预期的编译器错误,说它应该是一个string而不是一个number 不幸的是,这与现在一样好。

Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM