J'ai un peu de mal à trouver une documentation ou une explication claire pour la relation apparemment spéciale entre une classe TypeScript et une interface du même nom.
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;
}
Interfaces du même nom dans un module seront fusionnées :
interface Foo {
x: number;
}
interface Foo {
y: string;
}
let g = {} as Foo;
g.x; // OK
g.y; // OK
Une déclaration de classe crée à la fois une fonction constructeur et une déclaration de type , ce qui signifie essentiellement que toutes les classes peuvent être utilisées comme interfaces.
class Bar {
y: number;
}
interface IBaz extends Bar { } // includes y: number
class CBaz implements Bar {
y: number = 5;
}
Par conséquent, avoir une classe et une interface avec le même nom équivaut à avoir deux interfaces avec le même nom, et vous obtiendrez des conflits de fusion si les deux instances de l'interface déclarent à nouveau les mêmes membres avec des types différents.
Curieusement, TypeScript permettra cela:
export interface Foo {
readonly x: number;
}
export class Foo {
readonly x: number = 3;
}
mais cela n'autorisera pas get x() { return 3; }
même si les deux génèrent comme readonly x: number
, donc je peux seulement imaginer que le vérificateur de type les considère comme différents pendant la fusion même s'ils sont sémantiquement les mêmes ( c'est pourquoi vous pouvez étendre l'interface et spécifier la propriété en lecture seule en tant que fonction getter).