如果我按如下方式定义我的类型,它将遵循我想要的行为。
interface Foo {}
interface Bar {
a: string;
b: boolean;
c: Foo;
}
type x = keyof Bar; // "a" | "b" | "c"
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试添加索引签名,它会丢失我所有的预定义成员。
interface Bar {
[index: string]: any;
}
type x = keyof Bar; // string | number
Run Code Online (Sandbox Code Playgroud)
有没有办法在 TypeScript 中正确地做到这一点?
类似于:
type x = Exclude<Bar, { [index: string]: any }>; // never
Run Code Online (Sandbox Code Playgroud)
编辑 我尝试了类似于 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
Run Code Online (Sandbox Code Playgroud)
Foo1不起作用,由于某种原因,它的类型信息变为{}.
Foo2 确实有效,但智能感知并没有说明Foo2类型的变量Foo2。他们反而有Indexable<BaseFoo>。
我真的很想尝试对我的用户隐藏这种类型的按摩。不幸的是,让他们从Indexable<T>到来回转换是不可行的T。
对于具有索引签名的内容,没有通用的方法可以做到这一点。
在添加索引签名之前获取密钥:
interface Foo {}
interface BarCore {
a: string;
b: boolean;
c: Foo;
}
type Bar = BarCore & {
[index: string]: any;
}
type X = keyof BarCore; // a|b|c
Run Code Online (Sandbox Code Playgroud)
PS:尽量不要在根级别将索引签名与有效道具混合。而是使用嵌套对象模式
| 归档时间: |
|
| 查看次数: |
2522 次 |
| 最近记录: |