Typescript: Utilisez typeof avec generic

Créé le 15 déc. 2017  ·  3Commentaires  ·  Source: microsoft/TypeScript

Version TypeScript: version actuelle du terrain de jeu (?)

Code

class GenericGroup<T> {
  items: Array<T> = [];
  constructor(name: string) {}
}

type CheckboxValues = string;
type CheckboxesGroup = new (name: string) => GenericGroup<CheckboxValues>;
const Checkboxes: CheckboxesGroup = GenericGroup;
const checkboxes = new Checkboxes('checkboxes');
checkboxes.items.map(item => item.toUpperCase());


type RadioValues = string;
type RadiosGroup = typeof GenericGroup<RadioValues>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

lien

Comportement prévisible:

typeof GenericGroup<RadioValues>; équivaut à new (name: string) => GenericGroup<RadioValues>;

Comportement réel:

Erreur de syntaxe, car typeof GenericGroup<RadioValues>; n'est pas pris en charge.

Motivation:

Dans mon cas d'utilisation, j'ai une classe avec un générique (comme GenericGroup ) qui _extend_ une classe d'une bibliothèque tierce. La classe de la bibliothèque tierce utilise plusieurs paramètres dans son constructeur. Quand j'alias ma classe avec le générique rempli, je ne veux pas écrire les paramètres de la bibliothèque tierce à chaque fois (comme cela a été fait avec new (name: string) => GenericGroup<CheckboxValues>; ) car je ne les maintiens pas vraiment.

(Il semble y avoir plusieurs problèmes liés, mais je n'ai pas trouvé de problème avec exactement ce problème.)

Question

Commentaire le plus utile

L'opérateur 'typeof' n'est pas destiné à décrire le constructeur d'un type, mais plutôt le type d'une valeur. SomeGenericn'est pas une valeur, c'est un type en soi. Toute autre interface / type (comme celui défini ci-dessous) ne fonctionnera pas non plus de cette manière.

interface MyInterface {
    name: string;
}

let m: typeof MyInterface; // error "MyInterface only refers to a type, but is being used as a value here."

Une solution à cela consiste à définir un type générique pour décrire les constructeurs comme le fait Angular:

// angular/packages/core/src/type.ts

export interface Type<T> extends Function { 
    new (...args: any[]): T; 
}

depuis ( angulaire / packages / core / src / type.ts )

Exemple d'utilisation:

type RadioValues = string;
type RadiosGroup = Type<GenericGroup<RadioValues>>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

Tous les 3 commentaires

L'opérateur 'typeof' n'est pas destiné à décrire le constructeur d'un type, mais plutôt le type d'une valeur. SomeGenericn'est pas une valeur, c'est un type en soi. Toute autre interface / type (comme celui défini ci-dessous) ne fonctionnera pas non plus de cette manière.

interface MyInterface {
    name: string;
}

let m: typeof MyInterface; // error "MyInterface only refers to a type, but is being used as a value here."

Une solution à cela consiste à définir un type générique pour décrire les constructeurs comme le fait Angular:

// angular/packages/core/src/type.ts

export interface Type<T> extends Function { 
    new (...args: any[]): T; 
}

depuis ( angulaire / packages / core / src / type.ts )

Exemple d'utilisation:

type RadioValues = string;
type RadiosGroup = Type<GenericGroup<RadioValues>>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

Une chose subtile est que les fonctions de constructeur de classe générique ne sont pas contenues dans un type générique . Vous pouvez dire cela parce que le paramètre de type n'est pas dans la portée des membres statiques! C'est comme si vous aviez un type comme celui-ci

interface GenericCtor<T> {
  new(x: string): InstanceType<T>;
}

mais le vrai type est comme ça

interface GenericCtor {
  new<T>(x: string): InstanceType<T>;
}

Merci à vous deux. J'ai besoin de comprendre cela. Dans mon cas, je m'étend à partir d'un constructeur tiers ( React.Component ) donc je dois comprendre comment appliquer vos commentaires là-bas. Merci.

Cette page vous a été utile?
0 / 5 - 0 notes