186 votes

Classes statiques TypeScript

Je voulais passer de JS traditionnel à TypeScript parce que j'aime la syntaxe proche de C#. Mon problème est que je n'arrive pas à trouver comment déclarer des classes statiques en TypeScript.

En C#, j'utilise souvent les classes statiques pour organiser les variables et les méthodes, en les regroupant dans une classe nommée, sans avoir besoin d'instancier un objet. En vanilla JS, j'avais l'habitude de faire cela avec un simple objet JS :

var myStaticClass = {
    property: 10,
    method: function(){}
}

En TypeScript, j'opterais plutôt pour mon approche C-sharpy, mais il semble que les classes statiques n'existent pas en TS. Quelle est la solution appropriée à ce problème ?

1voto

Vous pouvez utiliser classes abstraites con public static readonly members pour obtenir quelque chose de très similaire à ce que vous recherchez. Je crois que vous cherchez quelque chose comme un struct de C# ou C/C++ pour organiser ensemble de petits morceaux de données.

Ce qui est bien avec les classes abstraites, c'est que

  • ils ne peuvent pas être instanciés,
  • ils ne peuvent être dérivés que de et
  • ils peuvent fournir des implémentations de base pour tout ou partie des méthodes qui y sont définies.

Vous pouvez même utiliser cette technique pour imiter en quelque sorte une enum (vous ne pouvez pas les allumer, par exemple) mais ont des propriétés qui peuvent être plus que des chaînes ou des chiffres.

// you can omit the public keyword because it's the default in TS, I left it here for clarity

export abstract class RequestTypes {
  public static readonly All = 'All types';
  public static readonly Partners = 'Partners';
  public static readonly Articles = 'Articles';
}

0voto

Devin Stokes Points 88

Je cherchais quelque chose de similaire et je suis tombée sur quelque chose appelé la Singleton Pattern .

Référence : Modèle singleton

Je travaille sur une classe BulkLoader pour charger différents types de fichiers et et je voulais utiliser le modèle Singleton pour cela. De cette façon, je peux charger des fichiers à partir de ma classe d'application principale et récupérer les fichiers chargés facilement à partir d'autres classes.

Voici un exemple simple de la façon dont vous pouvez créer un gestionnaire de score pour un jeu avec TypeScript et le modèle Singleton.

class SingletonClass {

private static _instance:SingletonClass = new SingletonClass();

private _score:number = 0;

constructor() {
    if(SingletonClass._instance){
        throw new Error("Error: Instantiation failed: Use SingletonDemo.getInstance() instead of new.");
    }
    SingletonClass._instance = this;
}

public static getInstance():SingletonClass
{
    return SingletonClass._instance;
}

public setScore(value:number):void
{
    this._score = value;
}

public getScore():number
{
    return this._score;
}

public addPoints(value:number):void
{
    this._score += value;
}

public removePoints(value:number):void
{
    this._score -= value;
}   }

Ensuite, n'importe où dans vos autres classes, vous auriez accès au Singleton par :

var scoreManager = SingletonClass.getInstance();
scoreManager.setScore(10); scoreManager.addPoints(1);
scoreManager.removePoints(2); console.log( scoreManager.getScore() );

0voto

jaguar7021 Points 11

Vous pouvez également utiliser le mot-clé namespace pour organiser vos variables, classes, méthodes et ainsi de suite. Voir doc

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    const lettersRegexp = /^[A-Za-z]+$/;
    const numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}

0voto

Kieran Ryan Points 509

Vous pouvez créer une classe dans Typescript comme suit :

export class Coordinate {
        static x: number;
        static y: number;
        static gradient() {
            return y/x;
        }
    }

et faire référence à ses propriétés et méthodes "sans" instanciation donc :

Coordinate.x = 10;
Coordinate.y = 10;
console.log(`x of ${Coordinate.x} and y of ${Coordinate.y} has gradient of ${Coordinate.gradient()}`);

Pour info, l'utilisation de backticks `` en conjonction avec la syntaxe d'interpolation ${} permet de mélanger facilement le code avec le texte :-)

0voto

Ma méthode préférée est d'utiliser simplement un objet const (principalement au lieu des enums) :

const RequestTypes2 = {
    All: 'All types',
    Partners: 'Partners',
    Articles: 'Articles',
} as const; // need the "const" to force the property types to be string literal types (hover RequestTypes2 to see!)

// now you can do this (hover AllowedRequestTypes to see the inferred type)
type AllowedRequestTypes = typeof RequestTypes2[keyof typeof RequestTypes2];

function doRequest(requestType: AllowedRequestTypes) {

}

// these should work 
doRequest('Partners');
doRequest(RequestTypes2.All);
doRequest(RequestTypes.Articles);   // the property's type is "Articles" (string literal type)

// this fails
doRequest('Incorrect');

Consulte ce terrain de jeu TS .

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