我正在尝试创建一个函数,该函数接受一个键和一个值,并更新键入对象上的相应键-值对。这是我所追求的基本示例。
Link to code sandbox with below code
type x = {
prop : number,
other : string
}
let dataToUpdate : x = {
prop: 1,
other: "string"
}
function updateKey(key : string, value : number | string) {
dataToUpdate[key] = value;
}
在上述实现中出现此错误。
元素隐式具有
'any'
类型,因为类型'string'
的表达式不能用于索引类型'x'
。 在类型'string'
上未找到参数类型为'x'
的索引签名。(7053)
更新 向我介绍了XY Problem的概念。以下是我追求的实际实现。我正在尝试在React中创建一个上下文,该上下文返回一个函数,该函数仅允许您更新存储在上下文中的对象内的特定属性
export function StoreProvider(props: any) {
const [storeData, setStoreData] = useState<StoreData>(initProviderData);
function setStoreKeyValue(keyToUpdate: keyof StoreData[], valueToSet: boolean | string | number | null){
let newStoreData = {...storeData);
const isStoreData = Object.keys(initProviderData).filter((key) => { key == keyToUpdate }).length > 1;
if (isStoreData && newStoreData) {
newStoreData[keyToUpdate] = valueToSet;
setStoreData(newStoreData)
}
}
return (
<StoreContext.Provider value={{ "storeData": storeData, "setStoreData": setStoreData }}>
{props.children}
</StoreContext.Provider>
)
}
答案 0 :(得分:4)
TLDR ;
updateKey<K extends keyof X>(key: K, value: X[K]) {
dataToUpdate[key] = value;
}
详细信息:
给予
interface X {
prop: number;
other: string;
}
let dataToUpdate: X = {
prop: 1,
other: "string"
};
TypeScript不允许我们通过任意属性键类型(例如dataToUpdate
)访问具有一组已知属性的类型良好的对象的属性,例如您的string
。
由于该语言知道dataToUpdate
的唯一键是"prop"
和"other"
,因此必须相应地限制更新功能的key参数。
虽然我们可以在参数列表key: "prop" | "other"
中明确写出联合类型,但是这种模式对JavaScript而言是如此重要,以至于TypeScript提供了keyof
类型运算符,该运算符生成所有属性的联合类型给定类型的键,允许我们编写
updateKey(key: keyof X, value: string | number) {
dataToUpdate[key] = value;
}
但是,我们尚未完成,因为该语言需要确保value
参数的类型与指定的key
的属性类型(以及恰好与{{1 }}必须是"prop"
,而number
必须是"other"
。
为了描述这一点,我们将声明调整如下
string
我们所做的是关联两个参数的类型,以使updateKey<K extends keyof X>(key: K, value: X[K])
的类型与value
指定的属性的类型匹配,无论何时调用该函数。
答案 1 :(得分:1)
@Aluan给出的答案是绝对正确的,但还有另一种方法。只需将动态键添加到您的类型中,如下所示:
type x = {
prop : number,
other : string,
[key: string]: string | number;
}