Hvordan kan jeg få et generisk TypeScript-grensesnitt til å arve fra et annet generisk grensesnitt?
Jeg har et grensesnitt, med flere elementer:
export interface Item {
id: string;
code: string;
createdAt: string;
updatedAt: string;
level: number;
seq: number;
hasChildren: boolean;
parentObject?: Item;
children?: Item[];
}
Jeg ønsket noe som Partial<T> som jeg hjelpsomt oppdaget her: Gjør alle egenskaper i et Typescript-grensesnitt valgfrie
Jeg vil imidlertid gjøre ett av feltene obligatorisk. Jeg implementerte dette:
export interface ItemUpdate extends Partial<Item> {
id: string;
}
og det kompilerte godt. Jeg vil imidlertid unngå å erklære det for hvert grensesnitt. Til det laget jeg det mer generisk:
export interface UpdateOf<T> extends Partial<T> {
id: string; // the ID is the only mandatory value for an update
}
Men det kompilerer ikke lenger, og returnerer følgende feil:
error TS2312: An interface may only extend a class or another interface.
Jeg kjører Angular 6.1.5, som kommer med Typescript 2.9 (så vidt jeg vet).
Svar #1
Feilmeldingen er utdatert; det er et åpent problem for å oppdatere den. Den gjeldende regelen er at en klasse eller et grensesnitt bare kan utvide en objekttype eller et snitt av objekttyper med statisk kjente medlemmer, siden kompilatoren trenger å sjekke om typene til egenskapene erklært i klassen eller grensesnittet er kompatible med typene til de tilhørende egenskapene (hvis noen) i basetypen. Medlemmene av Partial<Item> er statisk kjente, mens medlemmene av Partial<T> ikke er det. En løsning er å bruke en snittype i stedet for et under-grensesnitt:
export type UpdateOf<T> = Partial<T> & {id: string};
