TypeScript编译器对带显式类型const无报错的行为疑问
为什么
getBar和getBar2的类型检查结果不一样? 这个问题本质是TypeScript里字面量类型推断和类型拓宽的差异导致的,咱们一步步理清楚:
先看const BAR = 'bar'的情况
当你用const声明变量但不指定类型时,TypeScript会尽可能推断最精确的类型——这里它会把BAR的类型定为字符串字面量'bar',也就是说TypeScript明确知道这个变量的值只能是'bar',不会变。
所以在bar[BAR]这行代码里,TS能精准匹配到Bar接口里的bar属性,确定bar[BAR]的类型是Foo,那bar[BAR].foo自然就是number类型。你试图把number作为boolean返回,TS当然会报错,这完全符合预期。
再看const BAR2: string = 'bar'的情况
但你给BAR2显式指定了string类型后,TS就会把原本的字面量类型'bar'“拓宽”成通用的string类型。这时候TS就不确定BAR2的具体值了——它可能是'bar',也可能是任何其他字符串。
对于Bar接口来说,它只定义了bar这一个属性,没有通用的字符串索引签名,所以bar[BAR2]的类型会被推断成Foo | undefined(如果你开了strictNullChecks的话),或者更模糊的类型。这种情况下,TS没法确定bar[BAR2].foo到底是什么类型,甚至不确定bar[BAR2]是否存在,自然就不会触发“number不能赋值给boolean”的错误。
怎么让getBar2也触发错误?
如果你想让BAR2也保持精确的字面量类型,有两种办法:
- 删掉显式的
string类型声明,让TS自动推断:const BAR2 = 'bar' - 直接指定字面量类型:
const BAR2: 'bar' = 'bar'
改完之后,getBar2就会和getBar一样,触发类型不匹配的错误了。
内容的提问来源于stack exchange,提问作者icfantv
相关产品推荐
相关产品推荐

