TypeScript中为何将'true'作为类型编译通过?
这是个很典型的TypeScript类型注解和实例属性赋值混淆的问题,我来帮你把每个疑问点拆解清楚:
1. 为什么class MyClass { myMember: true; }能编译通过?
这段代码完全符合TypeScript的语法规范——你在这里写的true不是值,而是一个字面量类型。TypeScript允许用具体的字面量(比如true、'foo'、42)作为类成员的类型注解,用来约束这个成员只能取该字面量对应的唯一值。
但这里有个关键:你只给myMember声明了类型,却没有初始化它的值。在非严格模式下(也就是tsconfig.json里strict或strictPropertyInitialization未开启时),TypeScript不会强制要求类成员必须初始化,编译会正常通过,只是这个成员在运行时的实际值是undefined。
2. true在这里确实被识别为类型
没错,myMember: true;里的true是布尔字面量类型,它是boolean类型的子类型,代表这个成员只能被赋值为true(如果后续赋值false,TypeScript会直接报错)。但因为你没给它赋值,运行时这个属性实际上不存在(或者说值为undefined),这就是Angular无法识别到属性值的核心原因——Angular需要的是实例上存在的具体属性值,而不是一个仅在类型层面存在的约束。
3. tsconfig配置的潜在问题
如果你的tsconfig.json开启了strict: true(或者单独开启strictPropertyInitialization: true),TypeScript会直接抛出错误:Property 'myMember' has no initializer and is not definitely assigned in the constructor.,提醒你这个成员未初始化。
你当前编译无报错,大概率是因为tsconfig没有启用严格模式相关的规则,导致TypeScript没有检测到这个“仅声明类型但未赋值”的问题。
正确写法对比
你需要的是给类成员赋值,而不是仅声明类型,所以正确写法是:
class MyClass { myMember = true; }
这样myMember会被初始化为true,TypeScript也会自动推断它的类型为boolean(如果需要严格约束为只能是true,可以写成myMember: true = true;)。
另外,tslint没报错可能是因为你没有启用检查未初始化类成员的规则,比如no-uninitialized之类的,可以检查下tslint的配置项。
内容的提问来源于stack exchange,提问作者Juan

