Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

typescript - How to remove index signature using mapped types

Given an interface (from an existing .d.ts file that can't be changed):

interface Foo {
  [key: string]: any;
  bar(): void;
}

Is there a way to use mapped types (or another method) to derive a new type without the index signature? i.e. it only has the method bar(): void;

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Edit: Since Typescript 4.1 there is a way of doing this directly with Key Remapping, avoiding the Pick combinator. Please see the answer by Oleg where it's introduced.

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

It is based on the fact that 'a' extends string but string doesn't extends 'a'.


There is also a way to express that with TypeScript 2.8's Conditional Types.

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

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


type FooWithOnlyBar = Pick<Foo, KnownKeys<Foo>>;

You can make a generic out of that:

// Generic !!!
type RemoveIndex<T extends Record<any,any>> = Pick<T, KnownKeys<T>>;

type FooWithOnlyBar = RemoveIndex<Foo>;

For an explanation of why exactly KnownKeys<T> works, see the following answer:

https://stackoverflow.com/a/51955852/2115619


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...