typescript - 如果函数声明时没有 `const` 关键字,函数调用签名会出错

标签 typescript tsc

我是 TypeScript 新手,正在学习 Call Signatures ,如果我使用 letconst 关键字存储函数,我会不断收到错误。像这样:

调用签名

type Foo = {
    desc: string,
    (arg: string): void
}

如果我创建一个函数并使用 letvar 关键字存储它,

let bar: Foo = function(arg: string): void{
    console.log(arg);
}
bar.desc = 'baz';

我收到以下错误:

 error TS2741: Property 'desc' is missing in type '(arg: string) => void' but required in type 'Foo'.

但是,如果我将函数存储在常量变量中,它就会按预期工作

type Foo = {
    desc: string,
    (arg: string): void
}

const bar: Foo = function(arg: string): void{
    console.log(arg);
}
bar.desc = 'baz';

背后有什么具体原因吗?我错过了什么吗?

最佳答案

对向函数添加属性的支持是 introduced in TypeScript 3.1microsoft/TypeScript#26368 中实现。该功能具体记录为:

Allow JS-container (expando) property assignments in Typescript, but only for function declarations and function/arrow expressions used as initialisers of const variables.

所以这正在按预期工作;使用函数初始化的 const 变量可以添加属性,但不支持 letvar


奇怪的是,我没有看到任何权威来源来解释为什么 letvar 不受支持。相反,我所能提供的只是一个有根据的猜测:这是因为 control flow analysisfunction 语句和 const 变量上比在 varlet容易得多> 变量。 function 语句和 const 变量无法重新分配,因此一旦您知道函数上有一个额外的属性,该属性将继续存在,除非有人修改该属性直接地。另一方面,varlet 可以被重新分配,这意味着编译器需要检查以确保在添加属性及其属性之间没有发生这种情况。尝试使用,根据范围的不同,这可能会相当复杂。

因此,我的期望是添加该功能是为了支持简单的情况,而尚未支持更复杂的情况,因为对它们的需求并不大(如果有的话)。如果您有一些重要的用例(由于 const 不够充分的原因),您可能需要提交功能请求。

关于typescript - 如果函数声明时没有 `const` 关键字,函数调用签名会出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74851447/

相关文章:

typescript - 定义全局常量

compiler-errors - Webstorm 7的TypeScript转码错误

Angular6:自定义组件上的输入绑定(bind)未正确更新

node.js - npm 安装旧版本的( typescript 编译器)包

javascript - 如何将 JSX 导入 .tsx 文件(不在 React 中)?

typescript - 类型 'validate' 中的属性 'MappingService' 不可分配给基本类型 'IMappingService' typescript 2.8.0 中的同一属性

javascript - TypeScript 通过 tsc 命令 : Output to single file without concatenation

typescript - 如何从Typescript编译器中获取函数节点的完整代码函数体?

angular - 在 Angular 的 DI 中使用从库导入的工厂函数时 AOT 编译失败

javascript - 将外部 javascript 库导入 Typescript 以与 Node 一起使用