Hur man tar bort fält från ett TypeScript-gränssnitt via en extension


Låt oss säga att det finns ett gränssnitt som jag inte har kontroll över:

interface Original {
  name: string;
  size: number;
  link: SomeType;
}

Jag vill utöka detta gränssnitt, men faktiskt ta bort link så att jag får ett nytt gränssnitt som i praktiken är:

interface OriginalLite {
  name: string;
  size: number;
}

Hur kan jag göra detta?

Svar #1

Du kan använda mappade och konditionella typer för att uppnå detta. Vanligtvis kallar vi det du försöker göra Omit:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

(för TS3.5+, Omit-verktygstypen ingår i standardbiblioteket, så du behöver inte definiera den själv längre)

Så Omit<T, K> är i princip samma som T men utan några av egenskaperna i K. Du kan göra följande för att skapa ett nytt interface som kallas OriginalLite som saknar endast link:

interface OriginalLite extends Omit<Original, 'link'> {}

Observera att du inte utökar Original. Det beror på att att "utöka" i TypeScript betyder att göra en typ mer specifik (även kallat "insnävning"), men i ditt fall gör du det motsatta, det vill säga gör den mindre specifik (även kallat "utvidgning"). Det är därför extends Original inte finns med i den definitionen. Jag antar att det är okej för dig.

Låt oss testa det:

declare const originalLite: OriginalLite;
originalLite.name; // string
originalLite.size; // number
originalLite.link; // error, property 'link' does not exist on type 'OriginalLite'

Ser bra ut.

Svar #2

Exempel på att utelämna flera oönskade egenskaper från en typ och lägga till nya anpassade egenskaper.

type UnwantedKeys = "key1" | "key2"

interface MyNewType extends Omit<Original, <UnwantedKeys>> {
  newProp1: string
  newProp2: number
}

Svar #3

Bara för att tillägga: om du inte har en lista över nycklar du vill ta bort men bara ett gränssnitt kan du använda keyof för att få en lista över nycklar och utelämna dem.

Exempel :

interface RemoveThoseKeys {
  removeMe1: unknown
  removeMe2: unknown
}

interface AllKeys {
  keep1: unknown
  keep2: unknown
  removeMe1: unknown
  removeMe2: unknown
}

type KeysAfterRemoval = Omit<AllKeys, keyof RemoveThoseKeys>

Om du instansierar ett objekt med typen KeysAfterRemoval och använder automatisk komplettering i ditt IDE bör du endast få keep1 och keep2.

Relaterade artiklar