TypeScript 接口函数属性:有什么区别? [英] TypeScript Interface Function Property: What's the difference?

查看:86
本文介绍了TypeScript 接口函数属性:有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Can someone please explain, why in this code the assignment to the constant of type InterfaceA works, but the assignment to the constant of type InterfaceB throws an error:

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
};

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

For an online demo, see: http://www.typescriptlang.org/play/index.html?ssl=19&ssc=1&pln=1&pc=1#code/JYOwLgpgTgZghgYwgAgJLmvJBBZBvAWAChlkATAewGUKBbCMAC1AHNkAKMuMOALmQoAjAFYQEYAJT9BFCgBsIcEAG5iAX2LFQkWIhTodWCACF8xUpRr0mrfp258BIsZOQBeAHzIZ8xSvWaRDAAriDiwBQg5BSoYBxcPPx4yGAAngAOEPwAzmBQrMrIalLesgpKZkQAkFAMwVBRecEQqkQaRMQIkbnI2PwGmHq4bpVVlnQMzCAs-JSx6q1dID3G-Ri6SKYjhNXj1lMz0fNtrUA

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

To me, both interfaces are defining the same, only the notation is different.

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

If this is not a bug in TypeScript, and there is a real reason, then let's come to my second question: I need to specify, that "doSomething" is optional and can either be a function, or a RegExp:

interface InterfaceB {
  doSomething?: ((data: object) => boolean) | RegExp;
}`

如何使用 InterfaceA 的符号实现这一点?

How could I achieve this, with the notation of InterfaceA?

推荐答案

1.) methodfunction property 声明的区别:

1.) There is a difference between method and function property declaration:

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

interface InterfaceB {
  doSomething: (data: object) => boolean; // function as property declaration
}

2.) TypeScript 2.6 介绍强类型的编译器标志,sound 函数类型:

2.) TypeScript 2.6 introduces a compiler flag for stronger-typed, sound function types:

--strictFunctionTypes下检查函数类型参数位置逆变而不是双变.更严格的检查适用于所有函数类型除了那些源自方法或构造函数声明的函数类型.(我的重点)

Under --strictFunctionTypes function type parameter positions are checked contravariantly instead of bivariantly. The stricter checking applies to all function types, except those originating in method or constructor declarations. (my emphasis)

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

So in general that is a good thing. In your example, InterfaceB has following contract: "Every function that can deal with a general object is compatible". But you want to assign a function doIt, that expects specific objects of type { type: string; } as input. A client that uses InterfaceB thinks, it is enough to pass object, but the implementation doIt wants something more concrete, so you rightfully get that error.

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

In contrast, methods like doIt in InterfaceA are excluded from --strictFunctionTypes for practical reasons. The developers decided the type system to be not too pendantic with built-in methods of Array etc. to have a reasonable balance between correctness and productivity.

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

So, in favor of stronger types, I would prefer the following type, which works for your case (sample):

interface InterfaceB {
  doSomething: ((data: { type: string; }) => boolean) | RegExp;
}

这篇关于TypeScript 接口函数属性:有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆