typescript - 打字稿命名函数不同的行为。错误无法调用类型缺少调用签名的表达式
问题描述
type ResolverFn = () => any;
// type Notifications = () => any | number; // works as expected
type Notifications = ResolverFn | number;
// when using the named function, ResolverFn, it fails with error:
// "Cannot invoke an expression whose type lacks a call signature. Type 'Notifications' has no compatible call signatures."
// but it works with the unnamed () => any
type Query = {
notifications: Notifications;
};
const Query: Query = {
notifications() {}
};
const notifications: Notifications = () => {};
notifications();
Query.notifications();
上面的例子很简单,是从一个更复杂的例子中推导出来的。实际上,不存在签名是函数或数字的类型。在这里,它只是用来展示行为上的差异。
还有其他与此错误相关的问题,但我找不到我的具体问题的答案,即:
为什么命名函数和未命名函数有不同的行为?这是预期的行为吗?为什么?有解决方法吗?假设问题来自我们无法修改的外部包,即使它可能不正确。
解决方案
内联函数类型“有效”的原因是因为它没有做你认为它做的事情:它描述了一个any | number
由于优先规则而返回的函数。注意区别:
// A function returning either any or number
type A = () => any | number;
// Either a function returning any — or a number
type B = (() => any) | number;
否则它不起作用的原因是因为不清楚它notifications
是函数类型,它也可能是一个数字,并且数字是不可调用的。
正如@Przemyslaw Pietrzak 的回答所指出的,使用类型保护来缩小类型:
if (typeof notifications === "function") {
notifications();
}
推荐阅读
- r - 闪亮的条件下拉菜单
- flutter - Flutter(Dart) , webscraper 插件在不同的 url 上给出错误
- mysql - MySQL删除和内部连接问题
- java - 运行时的通用类类型参数详细信息
- typescript - 为什么打字稿抱怨依赖库的不可扩展性和只读违规?
- r - ggplot2 在构面网格内设置比例
- laravel - Laravel 惯性动态表单验证
- python - 通过 paramiko 运行 msi 安装程序并等待任务完成
- c# - 如何对返回 Unit.Value 的 MediatR 方法进行单元测试
- javascript - 当我使用未知的电子邮件或错误的密码登录时,我仍在导航并且我也没有收到警报