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
})