我想根据提供的键名获得正确的类型来访问对象属性。我想在下面获得对象的键。
我有以下对象,我想从中访问一些数据:
const source = {
sth: {
EXAMPLE: 'this is my example'
},
another: {
TEST: 'this is my test value'
}
};
访问功能:
function getMessage(context : keyof typeof source, msgKey: string) : string {
if(msgKey in source[context]) {
return source[context][msgKey]
}
}
通过keyof typeof source
,我得到了一级密钥-就像一个护身符。
如何获取较低级别的密钥?当然有了msgKey: string
时我会出错:
元素隐式具有'any'类型,因为类型'string'的表达式不能用于索引类型'{例如:string; } | {TEST:字符串; }'。 在类型'{上找不到参数类型为'string'的索引签名。 } | {TEST:字符串; }'
当然,我想getMessage('sth', 'EXAMPLE')
拿到'this is my example'
答案 0 :(得分:1)
根据编译器提示
在类型'{上未找到参数类型为'string'的索引签名。 } | {TEST:字符串; }'
您需要为source
的属性指定索引签名:
interface Source {
[key: string]: { // First level
[key: string]: string; // Second level
}
}
const source: Source = {
sth: {
EXAMPLE: 'this is my example'
},
another: {
TEST: 'this is my test value'
}
};
现在,您甚至不需要为第一级编写keyof typeof source
,因为已经从Source
界面中隐含了它:
function getMessage(context: string, msgKey: string): string {
if(msgKey in source[context]) {
return source[context][msgKey]
}
}
据我了解,无法为任何动态嵌套级别指定索引签名,因此您必须为每个级别显式指定索引签名。但是,使用泛型可以使事情变得简单一些:
type Indexed<T> = {
[key: string]: T;
}
const source: Indexed<Indexed<string>> = {
sth: {
EXAMPLE: 'this is my example'
},
another: {
TEST: 'this is my test value'
}
};
当对象具有三层或更多层嵌套时,这不是最优雅的读物,但是它是一个选择:
const source: Indexed<Indexed<Indexed<Indexed<string>>>> = {};