TypeScript类和具有相同名称的接口之间的关系 [英] Relationship between a TypeScript class and an interface with the same name

查看:355
本文介绍了TypeScript类和具有相同名称的接口之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在查找TypeScript类和具有相同名称的接口之间看似特殊的关系的任何清晰文档或解释时,我有些麻烦。

I'm having a bit of trouble locating any clear documentation or explanation for the seemingly-special relationship between a TypeScript class and an interface with the same name.


  • 与类同名的接口的意义是什么?

  • 为什么与接口共享名称的类会自动实现该接口?

  • 当类和接口名称相同时,为什么编译器会抱怨我对只读接口字段的getter实现,但是如果名称不同,则接受该实现?

  • 是否有解决这些问题的规范文档?

  • What's the significance of an interface with the same name as a class?
  • Why does a class that shares its name with an interface implement that interface automatically?
  • Why does the compiler complain about my getter implementation of a readonly interface field when the class and interface have the same name, but accept the implementation if the names are different?
  • Is there any canonical documentation addressing these questions?

代码:

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


推荐答案

同一名称的接口将被合并的模块

interface Foo {
    x: number;
}

interface Foo {
    y: string;
}

let g = {} as Foo;
g.x; // OK
g.y; // OK

一个类声明创建构造函数和类型声明,这实际上意味着可以使用所有类

A class declaration creates both a constructor function as well as type declaration, which essentially means that all classes can be used as interfaces.

class Bar {
    y: number;
}

interface IBaz extends Bar { } // includes y: number

class CBaz implements Bar {
    y: number = 5;
}

因此,具有相同名称的类和接口等同于具有两个具有相同名称的接口,如果该接口的两个实例重新声明具有不同类型的相同成员,则将发生合并冲突。

Therefore, having a class and an interface with the same name is equivalent to having two interfaces with the same name, and you will get merge conflicts if both instances of the interface re-declare the same members with different types.

足够奇怪的是,Typescript允许为此:

Strangely enough, Typescript will allow for this:

export interface Foo {
    readonly x: number;
}

export class Foo {
    readonly x: number = 3;
}

但不允许 get x() {返回3; } 即使它们都生成为 readonly x:number ,所以我只能想象类型检查器在合并过程中将它们视为不同,即使它们在语义上是相同的(这就是为什么您可以扩展接口并将readonly属性指定为getter函数的原因。)

but it won't allow get x() { return 3; } even though both of those generate as readonly x: number, so I can only imagine that the type checker considers them as different during merging even though they are semantically the same (this is why you can extend the interface and specify the readonly property as a getter function).

这篇关于TypeScript类和具有相同名称的接口之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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