Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

Relationship between a TypeScript class and an interface with the same name

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.

  • 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?

Code:

// 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;
}
question from:https://stackoverflow.com/questions/43055682/relationship-between-a-typescript-class-and-an-interface-with-the-same-name

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Interfaces of the same name within a module will be merged:

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.

Strangely enough, Typescript will allow for this:

export interface Foo {
    readonly x: number;
}

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

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...