您希望编译器将carLot
的类型设置为infer,以使其具有类型Car
的readonly
properties的已知键.嘿,甚至可能是Readonly<Car>
类型的,使用the Readonly
utility type来确保Car
的属性本身是readonly
.老实说,我不确定你是否真的在乎readonly
.
重要的是:不必指定两次键,一次在类型中,一次在对象文字值中,只需将它们写入对象文字中并进行推断即可.
有时您可以使用the satisfies
operator来完成此操作,但当我try 使用它时,无论如何都会将属性设置为非readonly
.哦,好吧.相反,您可以使用更通用的方法来编写generic帮助器函数,该函数只返回其输入,但指导推理.在本例中,它看起来如下所示:
const asCarLot = <K extends string>(
r: { readonly [P in K]: Readonly<Car> }
) => r;
现在,你写的是const carLot = asCarLot({⋯})
,而不是const carLot: SomeCarLotType = {⋯}
.如下所示:
const carLot = asCarLot({
oldCar: {
model: "acura",
year: 1998,
},
otherCar: {
model: "Mitsubishi",
year: 1995,
}
});
/* const carLot: {
readonly oldCar: Readonly<Car>;
readonly otherCar: Readonly<Car>;
} */
您可以看到,carLot
已被推断为所需类型.如果编辑对象文字以添加新条目,则carLot
的类型将相应更改:
const carLot = asCarLot({
oldCar: {
model: "acura",
year: 1998,
},
otherCar: {
model: "Mitsubishi",
year: 1995,
},
yetAnother: {
model: "Yugo",
year: 1994
}
});
/* const carLot: {
readonly oldCar: Readonly<Car>;
readonly otherCar: Readonly<Car>;
readonly yetAnother: Readonly<Car>;
} */
如果您编辑对象文字以将值设置为非Car
兼容类型,它将相应地发出错误:
const carLot = asCarLot({
oldCar: {
model: "acura",
year: "nineteen ninety eight", // error
},
otherCar: {
model: "Mitsubishi",
year: 1995,
color: "blue", // error
}
});
Playground link to code个