microsoft / microsoft/TypeScript

Polymorphic "this" for static members

Offen
#5,863 196 Kommentare 362 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

In Discussion Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der Überprüfung der Beispiele für polymorphes this in diesem Issue und den zugehörigen Issues #5493 und #5492. Ermittle die beabsichtigte Semantik des Typsystems sowie einen Implementierungs- und Testplan; „done“ soll ein vereinbartes, typsicheres Ergebnis für das Beispiel mit Factory/BaseModel bedeuten.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
20/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.