如何使用映射类型删除索引签名 [英] How to remove index signature using mapped types
问题描述
给定一个接口(来自无法更改的现有 .d.ts 文件):
Given an interface (from an existing .d.ts file that can't be changed):
interface Foo {
[key: string]: any;
bar(): void;
}
有没有办法使用映射类型(或其他方法)在没有索引签名的情况下派生新类型?即它只有方法 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;
推荐答案
从 Typescript 4.1 开始,有一种方法可以直接使用 键重映射,避免Pick
组合器.请参阅Oleg 的回答.
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]
};
它基于'a'扩展字符串
但string
不扩展'a'
的事实.
还有一种方法可以用 TypeScript 2.8 的 条件类型.
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>;
有关 KnownKeys<T>
究竟为何起作用的解释,请参阅以下答案:
For an explanation of why exactly KnownKeys<T>
works, see the following answer:
https://stackoverflow.com/a/51955852/2115619
这篇关于如何使用映射类型删除索引签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!