TypeScript带属性的函数类型别名示例运行报错如何解决
TypeScript带调用签名的类型实例构造问题
问题场景
我在查阅TypeScript官方文档函数相关章节时,看到如下类型别名示例代码:
type DescribableFunction = { description: string; (someArg: number): boolean; }; function doSomething(fn: DescribableFunction) { console.log(fn.description + " returned " + fn(6)); }
直接运行上述代码不会产生任何输出,原因是代码中并未调用doSomething函数。我尝试自行构造符合DescribableFunction类型的实例传入该函数完成调用,但编写的代码无法正常通过类型校验,不清楚该类型中调用签名对应的部分应该如何正确编写,测试代码如下:
type DescribableFunction = { description: string; (someArg: number): boolean; }; function doSomething(fn: DescribableFunction) { console.log(fn.description + " returned " + fn(6)); } const new_fn: DescribableFunction = { description: "test", () { // 不知道这里该怎么写 return true; }, }; doSomething(new_fn);
错误原因
你写的对象字面量不符合DescribableFunction的类型要求:
- 该类型描述的是本身可被调用,同时额外挂载了
description字符串属性的函数,不是「包含一个函数属性的普通对象」 - 类型定义里的
(someArg: number): boolean是调用签名,约束这个值本身可以被当作函数执行,入参为number类型、返回值为boolean类型,不是要求对象上存在某个具名函数属性 - 普通对象字面量默认无法直接通过
xxx()的形式调用,自然匹配不上调用签名的约束。
正确实现方案
JS中函数本身是特殊的对象,可以在函数上挂载自定义属性,刚好匹配这类带属性的函数类型要求,有两种常用的实现方式:
方式1:先定义函数,再挂载属性
这是最直观、兼容性最好的写法:
type DescribableFunction = { description: string; (someArg: number): boolean; }; function doSomething(fn: DescribableFunction) { console.log(fn.description + " returned " + fn(6)); } // 先实现符合调用签名要求的函数本体 function checkNumber(someArg: number): boolean { return someArg > 5; } // 给函数挂载要求的description属性 checkNumber.description = "判断输入数字是否大于5"; doSomething(checkNumber); // 运行输出:判断输入数字是否大于5 returned true
方式2:用Object.assign一次性合并定义
适合需要在定义时就写完所有逻辑的场景,TypeScript可以自动推导合并后的类型符合约束:
const new_fn: DescribableFunction = Object.assign( // 第一个参数传入符合调用签名的函数本体 (someArg: number) => { return someArg % 2 === 0; }, // 第二个参数传入要挂载的属性对象 { description: "判断输入数字是否为偶数" } ); doSomething(new_fn); // 运行输出:判断输入数字是否为偶数 returned false
内容的提问来源于stack exchange,提问作者Spooky
相关产品推荐
相关产品推荐

