假设我有以下接口和对象:
interface Person {
name: string;
lastName?: string;
}
const obj: { [key: string]: Person } = {
a: { name: 'John' },
b: { name: 'Jane', lastName: 'Doe' },
}
这定义了对象的类型,使其键可以是任何 string
。但是我希望仍然能够推断出对象的键(因为它是静态的),在这种情况下,我不能。
我可以这样做:
type ObjKeys = 'a' | 'b';
const obj: { [key in ObjKeys]: Person } //...
但它很冗长。
是否有一种简短的方式说“这里是这个对象的所有值的类型,但保留静态定义的键?”
答案 0 :(得分:1)
你不能纯粹在类型级别这样做;如果您使用 obj
annotate {[k: string]: Person}
的类型,那么编译器将假定这是要使用的实际类型,并且不会根据分配将其 narrow 为其他类型{a: {...}, b: {...}}
。此类 control flow analysis 仅适用于类型为 union 且 {[k: string]: Person}
不是联合的值。
在这种情况下,我通常做的是编写一个 generic 助手 identity function,编译器可以从中推断出您正在寻找的类型:
const asPersonDict = <K extends PropertyKey>(
o: { [P in K]: Person }) => o;
然后你调用辅助函数而不是注释类型:
const obj = asPersonDict({
a: { name: 'John' },
b: { name: 'Jane', lastName: 'Doe' },
});
/* const obj: {
a: Person;
b: Person;
} */