首页 > 解决方案 > 打字稿命名函数不同的行为。错误无法调用类型缺少调用签名的表达式

问题描述

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();

上面的例子很简单,是从一个更复杂的例子中推导出来的。实际上,不存在签名是函数或数字的类型。在这里,它只是用来展示行为上的差异。

还有其他与此错误相关的问题,但我找不到我的具体问题的答案,即:

为什么命名函数和未命名函数有不同的行为?这是预期的行为吗?为什么?有解决方法吗?假设问题来自我们无法修改的外部包,即使它可能不正确。

打字稿repl

标签: typescripttypes

解决方案


内联函数类型“有效”的原因是因为它没有做你认为它做的事情:它描述了一个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();
} 

推荐阅读