TypeScript报错类型不兼容:Object.freeze致字符串变量无法赋值
问题解析与解决方案
为什么赋值会报错?
当你用Object.freeze创建对象时,TypeScript会把每个属性值推断为字面量类型,而非宽泛的string类型。比如SomeEnum.VAL_1的类型是"VAL_1",SomeEnum.VAL_2是"VAL_2"——这两个是完全不同的字面量类型,所以类型为"VAL_1"的temp无法接收类型为"VAL_2"的temp2的值,尽管它们的运行时类型都是string。
readonly是否会传递给新变量?
不会。Object.freeze仅让对象自身的属性变为只读,但你用let声明的temp、temp2本身是可变变量,问题核心不是readonly,而是TypeScript推断的字面量类型限制了赋值范围。
解决方法(三种可选)
- 显式指定变量类型为string
直接给变量声明宽泛的string类型,打破字面量类型的限制:
let temp: string = SomeEnum.VAL_1; let temp2: string = SomeEnum.VAL_2; temp = temp2; // 现在可正常赋值
- 给冻结的对象指定类型
提前给Object.freeze的对象定义包含string类型的接口,让TypeScript不再推断字面量类型:
const SomeEnum = Object.freeze<{ VAL_1: string; VAL_2: string; }>({ VAL_1: 'VAL_1', VAL_2: 'VAL_2' }); let temp = SomeEnum.VAL_1; let temp2 = SomeEnum.VAL_2; temp = temp2; // 正常赋值
- 使用联合类型约束变量
如果想保留只能赋值枚举成员的限制,同时允许在成员间赋值,可以先提取联合类型:
const SomeEnum = Object.freeze({ VAL_1: 'VAL_1', VAL_2: 'VAL_2' }); // 提取所有枚举成员的联合类型:"VAL_1" | "VAL_2" type SomeEnumType = typeof SomeEnum[keyof typeof SomeEnum]; let temp: SomeEnumType = SomeEnum.VAL_1; let temp2: SomeEnumType = SomeEnum.VAL_2; temp = temp2; // 正常赋值,且只能赋值枚举内的成员
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

