Typescript: Finns det ett sätt att säga att en klass implementerar sin generiska typ?


Låt oss säga att jag har en AbstractPageComponent-klass som har en setData-metod:

abstract class AbstractPageComponent<TPageData extends object> {
  setData(data: TPageData) {
    Object.assign(this, data);
  }
}

Så frågan är hur man talar om för Typescript att AbstractPageComponent-klassen implementerar TPageData? Detta fungerar inte:

abstract class AbstractPageComponent<TPageData extends object> implements TPageData {...}

För närvarande är det inte särskilt praktiskt att använda denna abstrakta klass:

interface SomePageData {
  foo: FooItem;
  bar: BarItem;
}

export class SomePageComponent 
  extends AbstractPageComponent<SomePageData>
  implements SomePageData {
  foo: FooItem;
  bar: BarItem;
}

Det kräver att slutanvändaren skriver implements SomePageData och duplicerar alla dess fält. Det jag vill uppnå är detta:

interface SomePageData {
  foo: FooItem;
  bar: BarItem;
}

export class SomePageComponent 
  extends AbstractPageComponent<SomePageData> {
  someMethod() {
    // this.foo and this.bar are available
  }
}

Är det möjligt?

Svar #1

Nej, det är inte möjligt. Typescript behandlar klasser på ett helt annat sätt än andra typer som skapas med type eller interface-nyckelordet.

Koden du använder just nu är i princip den optimala lösningen enligt min åsikt.

Svar #2

Skulle du vänligen prova följande:

export class AbstractPageComponent<T> implements T {
}

Och i en annan fil:

interface SomePageData{
   foo: FooItem;
   bar: BarItem;
}

export class SomePageComponent extends AbstractPageComponent<SomePageData> {

}