为什么TypeScript中非可选属性的属性初始化是可选的?

为什么TypeScript中非可选属性的属性初始化是可选的?,typescript,types,Typescript,Types,考虑这个例子: class A { optional?: string; nonOptional: string; constructor() { } } let a = new A(); function consumeString(str: string) { console.log(str.length); } consumeString(a.optional); consumeString(a.nonOptional); 启用strict

考虑这个例子:

class A {
    optional?: string;
    nonOptional: string;
    constructor() {

    }
}

let a = new A();

function consumeString(str: string) {
    console.log(str.length);
}

consumeString(a.optional);
consumeString(a.nonOptional);
启用strictNullChecks后,TypeScript 2.4.2将拒绝第一次调用

类型为
'string | undefined'
的参数不能分配给类型为
'string'
的参数
类型“
undefined”不可分配给类型
'string'`

但是,在运行时,第二次调用也会失败,因为
a.nonOptional
不引用字符串


为什么TypeScript不强制初始化
非可选的

编译器不会告诉您如何编码。
您可以在任何给定时间自由赋值,只要它是字符串,编译器就不会争辩。如果你不这样做,那也是有效的

如果要防止出现这种情况,请将类型更改为:

nonOptional: string | undefined;
那么这个,

consumeString(a.nonOptional);
将导致:

类型为“string | undefined”的参数不能分配给的参数 键入“字符串”。
类型“未定义”不可分配给类型“字符串”


这是TypeScript 2.7中修复的TypeScript中的bug或错误设计

默认情况下,TypeScript 2.7会拒绝您的代码,并会说
非可选的
需要初始化

TypeScript 2.7引入了
strictPropertyInitialization
功能,要求类的必填字段必须在contstructor中初始化(或我的默认值)


(您可以禁用此检查,将
strictPropertyInitialization=false
传递给编译器,以还原为TypeScript@Aron谁声称ts是类型安全的?它为您提供了用于它的工具,但您总是会犯错误,这不正是防止您犯键入错误的关键吗?@Aron我不这么认为,因为您甚至都不是被迫这样做的。)使用类型系统。例如,您也不必使用
strictNullChecks
,在这种情况下,编译器不会抱怨本文中的任何代码部分。同样,您获得了这些工具,您可以选择如何/何时使用它们。这有助于避免类型错误,但不会阻止它们。类型安全和null检查是不同的.请参阅以供参考。我在TypeScript问题跟踪器上找到了。这是一个很好的链接,您应该将其作为完整答案写出来!