为所有值具有相同类型的对象定义类型
Define a type for an object where all values have the same type
我正在尝试为一个对象定义一个类型,这样该对象的每个值都具有相同的类型,并且必须具有相同的键。我希望能够在每个值都具有相同键的情况下执行此操作,定义为所有值类型的联合。
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
},
})
这里的类型错误是:
Type '{ x: number; y: number; }' is not assignable to type '{ x:
number; }'. Object literal may only specify known properties, and
'y' does not exist in type '{ x: number; }'.
我真的不知道如何用打字稿完成这件事,我怀疑这是不可能的 - 有人有什么建议吗?
@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,
},
})
我正在尝试为一个对象定义一个类型,这样该对象的每个值都具有相同的类型,并且必须具有相同的键。我希望能够在每个值都具有相同键的情况下执行此操作,定义为所有值类型的联合。
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
},
})
这里的类型错误是:
Type '{ x: number; y: number; }' is not assignable to type '{ x: number; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
我真的不知道如何用打字稿完成这件事,我怀疑这是不可能的 - 有人有什么建议吗?
@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,
},
})