我正在尝试为对象定义一种类型,以便该对象的每个值都具有相同的类型,并且必须具有相同的键。我希望能够在每个值具有相同键的情况下执行此操作,键定义为所有值的类型的并集。
const test = {
a: { // I'd like to see a type error on this line
x: 1,
},
b: {
x: 1,
y: 2,
},
}
可以提前定义类型:
interface IA {
[key: string]: {
x: number;
y: number;
}
}
const test: IA = {
a: { // now we get a type error because we don't have y on this object
x: 1,
},
b: {
x: 1,
y: 2,
},
};
我可以通过以下代码获得一些信息:
const test = <T>(x: { [key: string]: { [key in keyof T]: string } }) => true;
或者,我们可以在函数中推断类型,但是问题是它并没有采用所有类型的并集,而只采用对象中的第一个:
const test = <T>(x: { [key: string]: { [key in keyof T]: number } }) => true;
const x = test({
a: {
x: 1,
},
b: {
x: 1,
y: 2, // now we get a type error here
},
})
这里的类型错误是:
输入'{x:数字; y:数字; }'不可分配给类型'{x: 数; }'。对象文字只能指定已知属性,并且 'y'在类型'{x:number;中不存在; }'。
我真的不知道如何在打字稿中做到这一点,我怀疑这是不可能的-有人有什么建议吗?
答案 0 :(得分:1)
@ TitianCernicova-Dragomir here是一个很好的答案:
type UnionKeys<U> = U extends U ? keyof U : never;
const test = <T>(x: T & Record<keyof T, Record<UnionKeys<T[keyof T]>, number>>) => true;
const x = test({
a: {
x: 1,
},
b: {
x: 1,
y: 2,
},
})