TypeScript,啥是对象文字的调用签名以及它们如何与泛型类型一起使用?
Posted
技术标签:
【中文标题】TypeScript,啥是对象文字的调用签名以及它们如何与泛型类型一起使用?【英文标题】:TypeScript, what are call signature of an object literal and how can they be used with generic types?TypeScript,什么是对象文字的调用签名以及它们如何与泛型类型一起使用? 【发布时间】:2018-08-04 15:33:52 【问题描述】:我正在阅读TypeScript documentation 的这一部分,在泛型类型部分下,以下两个被声明为等效:
代码示例 1
function identity<T>(arg: T): T
return arg;
let myIdentity: <T>(arg: T) => T = identity;
代码示例 2
function identity<T>(arg: T): T
return arg;
let myIdentity: <T>(arg: T): T = identity;
文档指出这是可能的,原因如下。
我们也可以将泛型类型写成对象字面量类型的调用签名
尽管有这一行,我仍然在努力理解这两者是如何等价的,是否有任何进一步的文档或解释来说明“对象文字类型的调用签名”的含义。
很抱歉,我无法给出进一步的解释,但我完全不知道这两者是如何等价的,对我来说,第二种类型定义表明 myIdentity 应该是一个对象?
谢谢。
【问题讨论】:
【参考方案1】:函数可以具有属性,这就是对象字面量语法的用途:它允许定义调用签名和附加属性。您的两个示例是等效的,因为第二个示例没有在对象文字上定义其他属性。您可以在hybrid types 部分阅读更多内容。
此外,对象字面量允许为函数重载定义多个调用签名。你可以用Object.assign
创建这样一个接口的对象:
interface Foo
(x: string): number,
(x: number): string,
bar: Array<any>,
const foo: Foo = Object.assign(function (x: any)
if (typeof x === 'string')
return parseInt(x);
else
return x.toString();
,
bar: []
);
【讨论】:
【参考方案2】:这是因为 Function
在 javascript 中也是一个对象。
考虑以下几点:
function foo() return 'foo'
// vs
const foo = Object.assign(
function () return 'foo' ,
)
TypeScript 只是遵循 JavaScript 中的可能性。
【讨论】:
【参考方案3】:当我阅读 typescript 手册中的这个例子时,我也有同样的困惑。
现在我是这样理解的,但不是很确定:
interface MyFunc
(arg: string): string //define a function by a call signature
let myIdentity: MyFunc
let myIdentity2:
(arg: string): string //here is the body of MyFunc, the call signature
//the total is a call signature in an object literal type
myIdentity = identity
myIdentity2 = identity
所以有两种函数定义格式:
interface MyFunc
(arg: string): string //a call signature
funcName: (arg: string) => string //express of function in object literal
【讨论】:
【参考方案4】:按照 TypeScript 官方手册introduced(v3.7),
为了用接口描述函数类型,我们给接口一个调用签名。这就像一个只给出参数列表和返回类型的函数声明。
interface SearchFunc
(source: string, subString: string): boolean;
你会发现接口正是这样描述函数类型的,即“对象字面量”风格。
PS:我在浏览 TypeScript 官方手册时遇到了同样的问题。当我查看这个 SO 问题时,所有答案都指的是混合类型部分,我在其中没有找到我的答案......它源于 Function-Types 部分。
【讨论】:
【参考方案5】:其他答案暗示了这一点,但可能需要明确。简而言之,第二个例子是函数和对象的混合类型。
https://www.typescriptlang.org/docs/handbook/interfaces.html#hybrid-types
定义一个接口,如果你给它一个名为“(...)”的属性,括号没有名字,这意味着你的接口可以应用于函数。可以说,接口“是”函数的接口。如果您添加其他命名属性,则会出现混合部分,以强调其作为对象的状态。
对于某些读者来说,在修补此信息后,其他答案(很棒)可能更有意义。
【讨论】:
以上是关于TypeScript,啥是对象文字的调用签名以及它们如何与泛型类型一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
Typescript中的“无法调用类型缺少调用签名的表达式”?
route.component 没有任何构造或调用签名 - 使用 TypeScript 的 React Router