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>
