219 votes

Comment définir une propriété statique dans une interface TypeScript

Je veux juste déclarer un Propriété statique dans le langage courant interface ? Je n'ai rien trouvé à ce sujet.

interface myInterface {
  static Name:string;
}

Est-ce possible ?

191voto

Val Points 86

Suivez la réponse de @Duncan @Bartvds, ici pour fournir une voie praticable après les années passées.

À ce stade, après la publication de Typescript 1.5 (@15 juin 15), votre interface utile

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

peut être mis en œuvre de cette manière à l'aide d'un décorateur.

/* class decorator */
function staticImplements<T>() {
    return <U extends T>(constructor: U) => {constructor};
}

@staticImplements<MyTypeStatic>()   /* this statement implements both normal interface & static interface */
class MyTypeClass { /* implements MyType { */ /* so this become optional not required */
    public static staticMethod() {}
    instanceMethod() {}
}

Reportez-vous à mon commentaire sur github numéro 13462 .

résultat visuel : Erreur de compilation avec une indication de méthode statique manquante. enter image description here

Après l'implémentation d'une méthode statique, indication de la méthode manquante. enter image description here

La compilation est passée après que l'interface statique et l'interface normale aient été remplies. enter image description here

70voto

Steve Fenton Points 55265

Vous ne pouvez pas définir une propriété statique sur une interface en TypeScript.

Supposons que vous vouliez changer le Date plutôt que d'essayer d'ajouter aux définitions de l'objet Date vous pouvez l'envelopper, ou simplement créer votre propre classe de date pour faire ce que vous voulez. Date ne fait pas.

class RichDate {
    public static MinValue = new Date();
}

Étant donné que Date est une interface en TypeScript, vous ne pouvez pas l'étendre avec une classe en utilisant l'attribut extends ce qui est un peu dommage car ce serait une bonne solution si la date était une classe.

Si vous souhaitez étendre l'objet Date pour fournir une fonction MinValue sur le prototype, vous le pouvez :

interface Date {
    MinValue: Date;
}

Date.prototype.MinValue = new Date(0);

Appelé en utilisant :

var x = new Date();
console.log(x.MinValue);

Et si vous voulez le rendre disponible sans instance, vous pouvez également le faire... mais c'est un peu difficile.

interface DateStatic extends Date {
    MinValue: Date;
}

Date['MinValue'] = new Date(0);

Appelé en utilisant :

var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);

33voto

Benny Neugebauer Points 5393

Les modificateurs statiques ne peuvent pas apparaître sur un membre de type (erreur TypeScript TS1070). C'est pourquoi je recommande d'utiliser une classe abstraite pour résoudre la mission :

Exemple

// Interface definition
abstract class MyInterface {
  static MyName: string;
  abstract getText(): string;
}

// Interface implementation
class MyClass extends MyInterface {
  static MyName = 'TestName';
  getText(): string {
    return `This is my name static name "${MyClass.MyName}".`;
  }
}

// Test run
const test: MyInterface = new MyClass();
console.log(test.getText());

21voto

Kamil Szot Points 4521

Vous pouvez définir l'interface normalement :

interface MyInterface {
    Name:string;
}

mais tu ne peux pas juste faire

class MyClass implements MyInterface {
    static Name:string; // typescript won't care about this field
    Name:string;         // and demand this one instead
}

Pour exprimer qu'une classe doit suivre cette interface pour ses propriétés statiques, il faut un peu d'astuce :

var MyClass: MyInterface;
MyClass = class {
    static Name:string; // if the class doesn't have that field it won't compile
}

Vous pouvez même conserver le nom de la classe, TypeScript (2.0) n'y verra pas d'inconvénient :

var MyClass: MyInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that field it won't compile
}

Si vous voulez hériter de plusieurs interfaces de manière statique, vous devrez d'abord les fusionner en une nouvelle interface :

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
interface NameAndAddressInterface extends NameInterface, AddressInterface { }
var MyClass: NameAndAddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Ou si vous ne voulez pas nommer l'interface fusionnée, vous pouvez le faire :

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
var MyClass: NameInterface & AddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Travail exemple

17voto

duncan Points 522

Les propriétés statiques sont généralement placées sur le constructeur (global) de l'objet, tandis que le mot-clé "interface" s'applique aux instances de l'objet.

La réponse précédente est bien sûr correcte si vous écrivez la classe en TypeScript. Cela peut aider d'autres personnes de savoir que si vous décrivez un objet qui est déjà implémenté ailleurs, alors le constructeur global incluant les propriétés statiques peut être déclaré comme ceci :

declare var myInterface : {
  new(): Interface;
  Name:string;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X