microsoft / microsoft/TypeScript

Polymorphic "this" for static members

Abierto
#5,863 196 comentarios 362 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

In Discussion Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

When trying to implement a fairly basic, but polymorphic, active record style model system we run into issues with the type system not respecting this when used in conjunction with a constructor or template/generic.

I've posted before about this here, #5493, and #5492 appears to mention this behavior also.

And here is an SO post this that I made:
http://stackoverflow.com/questions/33443793/create-a-generic-factory-in-typescript-unsolved

I have recycled my example from #5493 into this ticket for further discussion. I wanted an open ticket representing the desire for such a thing and for discussion but the other two are closed.

Here is an example that outlines a model Factory which produces models. If you want to customize the BaseModel that comes back from the Factory you should be able to override it. However this fails because this cannot be used in a static member.

// Typically in a library
export interface InstanceConstructor<T extends BaseModel> {
    new(fac: Factory<T>): T;
}

export class Factory<T extends BaseModel> {
    constructor(private cls: InstanceConstructor<T>) {}

    get() {
        return new this.cls(this);
    }
}

export class BaseModel {
    // NOTE: Does not work....
    constructor(private fac: Factory<this>) {}

    refresh() {
        // get returns a new instance, but it should be of
        // type Model, not BaseModel.
        return this.fac.get();
    }
}

// Application Code
export class Model extends BaseModel {
    do() {
        return true;
    }
}

// Kinda sucks that Factory cannot infer the "Model" type
let f = new Factory<Model>(Model);
let a = f.get();

// b is inferred as any here.
let b = a.refresh();

Maybe this issue is silly and there is an easy workaround. I welcome comments regarding how such a pattern can be achieved.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza revisando los ejemplos de this polimórfico en este issue y los issues relacionados #5493 y #5492. Determina la semántica prevista del sistema de tipos y un plan de implementación y pruebas; «done» debe significar un resultado acordado y seguro para los tipos para el ejemplo de Factory/BaseModel.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
20/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.