如何使用映射类型删除索引签名 [英] How to remove index signature using mapped types

查看:60
本文介绍了如何使用映射类型删除索引签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个接口(来自无法更改的现有 .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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆