【发布时间】:2018-12-20 05:13:56
【问题描述】:
如果我如下定义我的类型,它将遵循我想要的行为。
interface Foo {}
interface Bar {
a: string;
b: boolean;
c: Foo;
}
type x = keyof Bar; // "a" | "b" | "c"
但是,如果我尝试添加索引签名,它会丢失我所有的预定义成员。
interface Bar {
[index: string]: any;
}
type x = keyof Bar; // string | number
有没有办法在 TypeScript 中正确执行此操作?
类似于:
type x = Exclude<Bar, { [index: string]: any }>; // never
编辑 我尝试了类似于 Jake 的解决方案并得到了这个:
interface Indexable<T> {
[index: string]: any;
}
type BaseType<T> = T extends Indexable<infer U> ? U : never;
interface BaseFoo {
Name: string;
}
interface Foo1 extends Indexable<BaseFoo> {}
type Foo2 = Indexable<BaseFoo>;
type base1 = BaseType<Foo1>; // {}
type base2 = BaseType<Foo2>; // BaseFoo
Foo1 不起作用,由于某种原因,其类型信息变为{}。
Foo2 确实 工作,但智能感知不会为 Foo2 类型的变量说 Foo2。他们改为Indexable<BaseFoo>。
我真的很想尝试对我的用户隐藏这种类型的按摩。不幸的是,让他们从Indexable<T> 到T 来回转换是不可行的。
【问题讨论】:
-
不要认为有办法做到这一点。一旦您将索引签名添加到组合
keyof将返回string,因此您无法访问命名键并且排除索引签名也是不可能的,因为任何具有签名的条件类型约束也将匹配属性 -
TypeScript: remove index signature using mapped types 的可能重复这个问题在技术上较早(10 天),但另一个问题有答案。
标签: typescript