TypeScript 类与同名接口之间的关系
Posted
技术标签:
【中文标题】TypeScript 类与同名接口之间的关系【英文标题】:Relationship between a TypeScript class and an interface with the same name 【发布时间】:2017-08-20 16:59:46 【问题描述】:对于 TypeScript 类和同名接口之间看似特殊的关系,我很难找到任何清晰的文档或解释。
接口与类同名有什么意义? 为什么与接口共享名称的类会自动实现该接口? 为什么当类和接口具有相同名称时,编译器会抱怨我的只读接口字段的 getter 实现,但如果名称不同则接受实现? 是否有解决这些问题的规范文档?代码:
// Co-named interface and class doesn't like readonly property implementation:
interface Foo
readonly x: number; // Error: Duplicate identifier 'x'
y: number;
class Foo
get x(): number // Error: Duplicate identifier 'x'
return 0;
y = 1;
// Same as above, but different class name + explicit `implements`
class Bar implements Foo
get x(): number // No error!
return 0;
y = 1;
// Duplicating the first example, but explicitly implementing the co-named interface:
interface Baz
readonly x: number; // Error: Duplicate identifier 'x'
y: number;
class Baz implements Baz
get x(): number // Error: Duplicate identifier 'x'
return 0;
y = 1;
【问题讨论】:
【参考方案1】:这是特定于访问者的限制,到目前为止,Typescript 团队在此问题上出现了unwilling to comment。
class Foo
readonly x: number = 0;
class Bar extends Foo
interface Bar
readonly x: 2;
const bar = new Bar();
bar.x; // type is 2, no error
团队commented 认为“[w] 属性是作为字段实现还是作为 getter/setter 对实现是实现细节,而不是类型的一部分”,但这是显然不是 Typescript 4.2 的情况:
class Baz extends Foo
// error: "'x' is defined as a property in class 'Foo',
// but is overridden here in 'Baz' as an accessor."
get x()
return 2;
我无法解释团队的反应。 getter/setter 不属于类型系统的评论来自 2015 年,可能已经过时了。
【讨论】:
TS4.3 beta 现在允许您向接口添加 getter 和 setter。也许这现在揭示了它们在内部的表现方式是多么不同。【参考方案2】:模块will be merged内的同名接口:
interface Foo
x: number;
interface Foo
y: string;
let g = as Foo;
g.x; // OK
g.y; // OK
类声明创建both a constructor function as well as type declaration,这实质上意味着所有类都可以用作接口。
class Bar
y: number;
interface IBaz extends Bar // includes y: number
class CBaz implements Bar
y: number = 5;
因此,一个类和一个接口同名就相当于两个接口同名,如果接口的两个实例都重新声明了不同类型的相同成员,就会产生合并冲突。
奇怪的是,Typescript 允许这样做:
export interface Foo
readonly x: number;
export class Foo
readonly x: number = 3;
但它不允许get x() return 3;
,即使它们都生成为readonly x: number
,所以我只能想象类型检查器在合并期间认为它们是不同的,即使它们在语义上是相同的(这就是为什么你可以扩展接口并将只读属性指定为getter函数)。
【讨论】:
谢谢。发布了一个问题,以澄清编译器为何以这种方式抱怨:github.com/Microsoft/TypeScript/issues/14882 @NathanRidley 您收到的对您的问题的“回复”很不幸,并且没有很好地反映打字稿团队。以上是关于TypeScript 类与同名接口之间的关系的主要内容,如果未能解决你的问题,请参考以下文章