Hur man utelämnar [key:string]: any från en typ i TypeScript?


Säg att jag har

interface A {
  apple?: number;
  [key: string]: any;
}

interface B extends A {
  banana?: number;
}

Jag vill att en typ C ska utvidga allt från A och allt från B utom [key: string]: any;. Jag vill att en typ D ska ärva allt från B utom allt från A.

Hur skapar jag C och D i TypeScript?

Svar #1

Välj allt från B, ta bort A indexsignatur:

type C = Pick<B, KnownKeys<B>>;

Välj allt från B, uteslut allt från A, ta bort A indexsignatur:

type D = Omit<C, KnownKeys<A>>

Typen KnownKeys<T> tar bort indexsignaturen för T och använder endast de kända egenskapsnycklarna (kredit till Mihail Malostanidis och hans svar här och här):

type KnownKeys<T> = {
    [K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;

Hur ser typerna C och D ut?

type C = {
    banana?: number | undefined;
    apple?: number | undefined;
}

type D = {
    banana?: number | undefined;
}

const c: C = {
    apple: 1,
    banana: 2,
}

const d: D = {
    banana: 2
}

Lekplats

Svar #2

Detta borde fungera:

type NoStringIndex<T> = { [K in keyof T as string extends K ? never : K]: T[K] };

interface A {
  apple?: number;
  [key: string]: any;
}

type A2 = NoStringIndex<A>

Relaterade artiklar