typescript - Bedre måde at udvide flere interfaces på


God aften,

Bare en hurtig en, jeg er ikke særlig god til TypeScript og finder stadig min vej rundt i generics. Der må da være en mere ren eller pæn måde at gøre følgende på, hvad ville den bedste fremgangsmåde være i dette scenario?

export interface Fruit {
  colour: string;
  age: number;
  edible: boolean;
}

export interface A {
  Apple: Fruit[];
  Banana: Fruit[];
  Peach: Fruit[];
  Plum: Fruit[];
  Melon: Fruit[];
}

export interface B {
  diffApple: Fruit[];
  diffBanana: Fruit[];
  diffPeach: Fruit[];
  diffPlum: Fruit[];
  diffMelon: Fruit[];
}

export interface FruitIndex
  extends A, B, (etc)

Jeg har denne situation, men for flere interfaces, og det ser bare virkelig rodet ud. På forhånd tak

Svar #1

Jeg forventer, at "pæn", "ordentlig" og "ren" er subjektive begreber. Du kunne omstrukturere definitionerne af A og B for at gøre dem mindre overlappende. For A:

export type A = Record<"Apple" | "Banana" | "Peach" | "Plum" | "Melon", Fruit[]>;

Her bruger vi hjælpeværktøjstypen Record<K, T>, en kortlagt type, som giver den samme egenskabsværdi-type T for hver af nøglerne i unionen K. Du kan kontrollere, at typen er som forventet:

/* type A = {
    Apple: Fruit[];
    Banana: Fruit[];
    Peach: Fruit[];
    Plum: Fruit[];
    Melon: Fruit[];
} */

Så for type B:

export type B = { [K in keyof A as `diff${K}`]: A[K] }

Her bruger vi nøgleomkortlægning i kortlagte typer sammen med skabelon-litteraltyper for at tilføje "diff" foran alle nøglerne i A samtidig med, at værdierne forbliver de samme. Igen kan du kontrollere, at typen er som forventet:

/* type B = {
    diffApple: Fruit[];
    diffBanana: Fruit[];
    diffPeach: Fruit[];
    diffPlum: Fruit[];
    diffMelon: Fruit[];
} */

Denne kode er mere kortfattet end dine oprindelige versioner af A og B... men jeg ved ikke, om den er mere "rydderlig". Der er noget at sige for kode, der kan forstås af ikke-eksperter. En person, der ser { [K in keyof A as `diff${K}`]: A[K] } og ikke ved, hvad det betyder, ville sandsynligvis ikke beskrive det som "ren".


For dit FruitIndex ser jeg ingen måde at gøre det mere kortfattet på; et sted skal du liste alle de overordnede interfaces, du ønsker at udvide. Du gør det enten efter ordet extends her, eller du laver en anden struktur, der lister det op og beregner FruitIndex ud fra det. Under alle omstændigheder vil du skrive A og B en anden gang et eller andet sted. Så jeg ville lade det være som det er, i hvert fald for dette eksempel:

export interface FruitIndex extends A, B { }

Playground-link til kode

Relaterede artikler