Javascript 强类型对象中的TypeScript循环约束
我已经声明了这样一个对象:Javascript 强类型对象中的TypeScript循环约束,javascript,typescript,object,types,Javascript,Typescript,Object,Types,我已经声明了这样一个对象: const示例={ 早上好:(name)=>‘早上好${name}!’, 晚上好:(name)=>`晚上好${name}` } 在其原始形式中,对象具有强类型键(我可以使用点表示法访问它们),但值可以是任何值。这就是我决定引入类型签名的原因: const示例:{ [K:string]:(名称:string)=>string; } = { 早上好:(name)=>‘早上好${name}!’, 晚上好:(name)=>`晚上好${name}` } 现在我的对象值是强类
const示例={
早上好:(name)=>‘早上好${name}!’,
晚上好:(name)=>`晚上好${name}`
}
在其原始形式中,对象具有强类型键(我可以使用点表示法访问它们),但值可以是任何值。这就是我决定引入类型签名的原因:
const示例:{
[K:string]:(名称:string)=>string;
} = {
早上好:(name)=>‘早上好${name}!’,
晚上好:(name)=>`晚上好${name}`
}
现在我的对象值是强类型的,但键不是,我可以尝试使用点符号访问任何键,而不必使用TypeScript抱怨(例如,我可以编写console.log(example.doesntexist)
,并且我也不会获得对象键的编辑器自动完成)。所以我试了一下:
const示例:{
[K in keyof typeof example]:(名称:string)=>string;
} = {
早上好:(name)=>‘早上好${name}!’,
晚上好:(name)=>`晚上好${name}`
}
现在我得到了一个循环约束错误(类型参数“K”有一个循环约束
,并且'example'在其自身的类型注释中直接或间接引用)。我知道我可以这样做
const示例:{
[K在‘晨’|‘晚’]:(名称:string)=>string;
} = {
早上好:(name)=>‘早上好${name}!’,
晚上好:(name)=>`晚上好${name}`
}
但这是多余的(我讨厌冗余/代码重复)。有什么方法可以实现我想要的吗?如果没有至少一些额外的代码,就无法实现这一点
在这种情况下,我通常编写一个通用的helper函数。这与您尝试编写的循环注释非常相似:
const asExample = <K extends PropertyKey>(
x: { [P in K]: (name: string) => string }
) => x;
您可以看到,示例
已知在早晨
和晚上
键上有属性,但在白天
键上没有属性
如果您试图对错误的输入调用asExample()
,您将得到所需的错误:
const badExample = asExample({
afternoon: name => `Good afternoon ${name}!`.length, // error!
// --------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// number is not assignable to string
night: "Good night everyone!" // error!
// ~~~~~ <-- string is not assignable to (name: string) => string
})
const badExample=a示例({
下午:name=>`下午好${name}!`.length,//错误!
// --------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//数字不能分配给字符串
晚上:“大家晚安!”//错误!
//~~~~~~字符串
})
“但是值可以是任何东西”-不,它们是字符串返回函数。这有什么不对?@Bergi我想要求所有值都是字符串返回函数,以避免出现错误。为什么您为示例对象声明了类型?ts将为您推断@Nur正如我已经说过的,我正在设置一个类型,要求所有对象值都必须是字符串返回函数,这样我可以期望objectPlus中的每个项都有相同的行为,你想要自动完成,对吗?据我所知,您还需要指定的键
,例如让示例:记录字符串>代码>
const badExample = asExample({
afternoon: name => `Good afternoon ${name}!`.length, // error!
// --------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// number is not assignable to string
night: "Good night everyone!" // error!
// ~~~~~ <-- string is not assignable to (name: string) => string
})