TypeScript 接口函数属性:有什么区别?

Jen*_*tke 13 properties interface function typescript

有人可以解释一下,为什么在这段代码中对 InterfaceA 类型的常量赋值有效,但对 InterfaceB 类型的常量赋值会引发错误:

interface InterfaceA {
  doSomething (data: object): boolean;
}

interface InterfaceB {
  doSomething: (data: object) => boolean;
}

function doIt (data: { type: string; }): boolean {
    return true;
}

const A: InterfaceA = {
    doSomething: doIt
};
const B: InterfaceB = {
    doSomething: doIt
};

Run Code Online (Sandbox Code Playgroud)

对于一个在线演示,请参阅: http://www.typescriptlang.org/play/index.html?ssl=19&ssc=1&pln=1&pc=1#code/JYOwLgpgTgZghgYwgAgJLmvJBBZBvAWAChlkATAewGUKBbCMAC1AHNkAKMuMOALmQoAjAFYQEYAJT9BFCgBsIcEAG5iAX2LFQkWIhTodWCACF8xUpRr0mrfp258BIsZOQBeAHzIZ8xSvWaRDAAriDiwBQg5BSoYBxcPPx4yGAAngAOEPwAzmBQrMrIalLesgpKZkQAkFAMwVBRecEQqkQaRMQIkbnI2PwGmHq4bpVVlnQMzCAs-JSx6q1dID3G-Ri6SKYjhNXj1lMz0fNtrUA

对我来说,两个接口的定义相同,只是符号不同。

如果这不是 TypeScript 中的错误,并且有真正的原因,那么让我们来回答我的第二个问题:我需要指定,“doSomething”是可选的,可以是函数,也可以是 RegExp:

interface InterfaceB {
  doSomething?: ((data: object) => boolean) | RegExp;
}`
Run Code Online (Sandbox Code Playgroud)

我怎么能用InterfaceA的符号实现这一点?

for*_*d04 18

1.)方法函数属性声明的区别:

interface InterfaceA {
  doSomething(data: object): boolean; // method declaration
}

interface InterfaceB {
  doSomething: (data: object) => boolean; // function as property declaration
}
Run Code Online (Sandbox Code Playgroud)

2.) TypeScript 2.6为强类型、健全的函数类型引入了编译器标志:

--strictFunctionTypes函数类型下,参数位置被逆变而不是双变量检查。在严格的检查适用于所有类型的函数除了那些原产于方法或构造函数声明(我的重点)

所以总的来说,这是一件好事。在您的示例中,InterfaceB具有以下合同:“可以处理将军的每个功能object都是兼容的”。但是您想分配一个函数doIt,该函数需要特定类型的对象{ type: string; }作为输入。使用的客户端InterfaceB认为,通过 就足够了object,但是实现需要doIt更具体的东西,所以你理所当然地得到那个错误。

为什么错误不会发生在InterfaceA

相比之下,方法就像doItInterfaceA排除--strictFunctionTypes实际原因。开发人员决定类型系统不要太依赖于内置方法Array等,以便在正确性和生产力之间取得合理的平衡。

因此,为了支持更强的类型,我更喜欢以下类型,它适用于您的情况(示例):

interface InterfaceB {
  doSomething: ((data: { type: string; }) => boolean) | RegExp;
}
Run Code Online (Sandbox Code Playgroud)