Typescript: Utilice typeof con genérico

Creado en 15 dic. 2017  ·  3Comentarios  ·  Fuente: microsoft/TypeScript

Versión de TypeScript: versión actual del parque infantil (?)

Código

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());

enlace

Comportamiento esperado:

typeof GenericGroup<RadioValues>; es equivalente a new (name: string) => GenericGroup<RadioValues>;

Comportamiento real:

Error de sintaxis, porque typeof GenericGroup<RadioValues>; no es compatible.

Motivación:

En mi caso de uso, tengo una clase con un genérico (como GenericGroup ) que _extiende_ una clase de una biblioteca de terceros. La clase de la biblioteca de terceros usa múltiples parámetros en su constructor. Cuando alias mi clase con el genérico relleno, no quiero escribir los parámetros para la biblioteca de terceros cada vez (como se hizo con new (name: string) => GenericGroup<CheckboxValues>; ) ya que realmente no los mantengo.

(Parece haber varios problemas relacionados, pero no pude encontrar un problema exactamente con este problema).

Question

Comentario más útil

El operador 'typeof' no está destinado a describir el constructor de un tipo, sino el tipo de un valor. SomeGenericno es un valor, es un tipo en sí mismo. Cualquier otra interfaz / tipo (como la que se define a continuación) tampoco funcionará de esta manera.

interface MyInterface {
    name: string;
}

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

Una solución a esto es definir un tipo genérico para describir constructores como lo hace Angular:

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

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

de ( angular / paquetes / core / src / type.ts )

Ejemplo de uso:

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

Todos 3 comentarios

El operador 'typeof' no está destinado a describir el constructor de un tipo, sino el tipo de un valor. SomeGenericno es un valor, es un tipo en sí mismo. Cualquier otra interfaz / tipo (como la que se define a continuación) tampoco funcionará de esta manera.

interface MyInterface {
    name: string;
}

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

Una solución a esto es definir un tipo genérico para describir constructores como lo hace Angular:

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

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

de ( angular / paquetes / core / src / type.ts )

Ejemplo de uso:

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

Una cosa sutil es que las funciones de constructor de clases genéricas no están contenidas en un tipo genérico . ¡Puede decirlo porque el parámetro de tipo no está dentro del alcance de los miembros estáticos! "Se siente" como si tuvieras un tipo como este

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

pero el tipo real es así

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

Gracias a los dos. Necesito envolver mi cabeza alrededor de esto. En mi caso, me extiendo desde un constructor de terceros ( React.Component ), por lo que necesito averiguar cómo aplicar sus comentarios allí. Gracias.

¿Fue útil esta página
0 / 5 - 0 calificaciones