TypeScript中如何通过字符串访问嵌套namespace并解决索引类型报错
问题原因
XX 是固定结构的命名空间对象,你当前用string类型的name变量索引它时,TS无法验证name一定是XX上已存在的属性,因此触发隐式any报错。
解决方案
方案1:类型收窄(推荐)
- 先基于已有的
XX命名空间定义,提取它的所有子命名空间键组成联合类型
type XXNamespaceKey = keyof typeof XX // 该类型会自动推导为`XX`下所有子命名空间名称的联合,比如示例中的`'Blue'`
- 修改
AssetTypeCongig.getName的返回值类型,从宽泛的string收窄为上面定义的XXNamespaceKey
// 原类型定义示例 // getName(type: AssetType): string // 修改后 getName(type: AssetType): XXNamespaceKey
- 调整
AssetHelper中的变量类型声明,不需要手动标注name为string,让TS自动推断类型即可
export const AssetHelper = (input: InputProto, type: AssetType) => { const name = AssetTypeCongig.getName(type) const encoded = XX[name].Proto.InputProto.encode(input).finish() const output = DoSothing.sign(encoded, type); return XX[name].Proto.OutputProto.decode(output) };
如果需要进一步保证XX下所有子命名空间结构统一,可以补充定义统一结构约束:
interface XXSubNamespace { Proto: { InputProto: { encode: (input: InputProto) => { finish: () => Uint8Array } }, OutputProto: { decode: (buf: Uint8Array) => unknown } } } // 确保XX的所有子属性符合该结构 const XX: Record<XXNamespaceKey, XXSubNamespace> = { // 原有命名空间实现 } as const
方案2:类型断言(快速验证用,不推荐长期使用)
如果暂时不想调整上游类型定义,可以直接通过类型断言强制告知TS你确定name是合法索引:
export const AssetHelper = (input: InputProto, type: AssetType) => { const name = AssetTypeCongig.getName(type) as keyof typeof XX const encoded = XX[name].Proto.InputProto.encode(input).finish() const output = DoSothing.sign(encoded, type); return XX[name].Proto.OutputProto.decode(output) };
内容的提问来源于stack exchange,提问作者steven
相关产品推荐
相关产品推荐

