TypeScript技术问题:无法通过变量键访问对象属性
解决TypeScript索引Emoji类型时的"any"类型错误
我来帮你搞定这个TypeScript的类型报错问题!先看看你遇到的错误:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Emoji'. No index signature with a parameter of type 'string' was found on type 'Emoji'
问题原因
你的两个常量EMOJI_NAME_KEY和EMOJI_UNICODE_KEY被TypeScript默认推断成了宽泛的string类型,但你的Emoji接口只允许用"n"和"u"这两个特定字符串作为索引,并不是任意字符串。当你用类型为string的常量去索引Emoji对象时,TS无法确定这个字符串是不是接口里允许的键,所以就抛出了这个错误。
另外还要提一句:你初始化emoji对象时,[EMOJI_NAME_KEY]赋值的是单个字符串'thumb',但接口里这个字段要求是string[](字符串数组),这里也会有类型错误,后面的解决方案里我会一起修正。
解决方案
方案1:用as const把常量锁定为字面量类型
直接给两个常量加上as const,让TypeScript知道它们的类型是具体的字符串字面量,而不是宽泛的string:
export const EMOJI_NAME_KEY = "n" as const; export const EMOJI_UNICODE_KEY = "u" as const; export interface Emoji { [EMOJI_NAME_KEY]: string[]; [EMOJI_UNICODE_KEY]: string; } // 修正数组赋值的问题,把'thumb'改成['thumb'] const emoji: Emoji = { [EMOJI_NAME_KEY]: ['thumb'], [EMOJI_UNICODE_KEY]: 'some_unicode_key' } // 现在访问就不会报错了 console.log(emoji[EMOJI_NAME_KEY]);
方案2:用联合类型统一管理键(更适合扩展场景)
如果以后可能需要新增更多Emoji相关的键,可以先定义一个联合类型,再基于它构建接口和常量:
// 定义所有允许的Emoji键 type EmojiKey = "n" | "u"; // 让常量属于这个联合类型 export const EMOJI_NAME_KEY: EmojiKey = "n"; export const EMOJI_UNICODE_KEY: EmojiKey = "u"; // 用映射类型构建接口,明确每个键对应的类型 export interface Emoji { [key in EmojiKey]: key extends typeof EMOJI_NAME_KEY ? string[] : string; } const emoji: Emoji = { [EMOJI_NAME_KEY]: ['thumb'], [EMOJI_UNICODE_KEY]: 'some_unicode_key' } console.log(emoji[EMOJI_NAME_KEY]); // 正常运行
这样以后要加新键,只需要修改EmojiKey联合类型就行,扩展性更好。
内容的提问来源于stack exchange,提问作者Moni
相关产品推荐
相关产品推荐

