TypeScript如何在对象上设置键值



我遇到了一个关于在普通对象上设置键/值的问题。

type getAObjectFn = <K extends string, V>(k: K, v: V) => Record<K, V>
const getAObject: getAObjectFn = (k, v) => {
return {
[k]: v
}
}
console.log(getAObject("foo", "bar"))

代码真的很简单,而我得到错误:

Type '{ [x: string]: V; }' is not assignable to type 'Record<K, V>'.

为什么我会出现这个错误?我的意思是k有一个扩展字符串的类型k,所以我认为它们是相同的。如何得到正确的结果?

顺便说一句,getAObject("foo", "bar")的类型显示Record<"foo",string>,为什么不显示Record<"foo","bar">Record<string,string>

操场

如果不需要使用比字符串更精确的类型,我建议将键设置为string

type getAObjectFn = <V>(k: string, v: V) => Record<string, V>
const getAObject: getAObjectFn = (k, v) => {
return {
[k]: v
}
}

然而,如果你想要一个更精确的类型,你可以进行类型转换,在这种情况下应该是安全的。

type getAObjectFn = <K extends string, V>(k: K, v: V) => Record<K, V>
const getAObject: getAObjectFn = (k, v) => {
return {
[k]: v
} as Record<typeof k, typeof v>
}

我的猜测是,您需要这样做的原因是[]-运算符没有保留k的类型(只是我的猜测(。通过执行类型转换,可以恢复键的类型。

此外,我猜测getAObject("foo", "bar")返回Record<"foo",string>的原因是类型K extends string使编译器寻找比string更具体的类型并找到类型"foo",而对于V,它满足于string

最新更新