我知道一般的解释是编译器进行静态类型检查,但是编译器具体使用什么方法来验证没有可空类型意外发挥作用?
2 回答
可空性/未定义性检查只是类型系统对类型建模方式的改变。像往常一样,这一切都发生在类型检查阶段,并且在发出的 JavaScript 中没有任何东西可以在运行时强制执行。
无论如何,您可以将类型视为values 的域。例如, 的域boolean
通常只是两个值true
和false
。string
是一个无界域,包含类似"hello"
and"world"
和所有其他字符串的字符串。
TypeScript 检查当某个值用于某个类型位置时,该值是否在该类型的域中。例如,true
is 不在number
's 域中,因此尝试在预期使用true
a 的位置是非法的。number
在没有严格 null 检查的 TypeScript 中,null
并且undefined
在每个 type 的域中。所以该类型boolean
实际上有四个值:true
、false
、undefined
和null
。正如人们通常发现的那样,这很糟糕,因为undefined
and 的行为与 and不null
完全相同。对于有属性和方法的东西,就更糟糕了,因为在except和的域中作为每个值的方法存在,所以真的很烦人。true
false
substr
string
null
undefined
在 TypeScript中进行严格的 null 检查,null
并undefined
移出每种类型的域并进入它们自己的类型。现在该值null
不能在string
预期 a 的地方使用,因为它不再在string
' 域中。该类型string | null
现在表示一个值,它可能是string
域的某个成员或特殊值null
。
这个解释改编自Anders Hejlsberg 从 Build 2016 大约 44:30 开始的演讲,正如您可能想象的那样,他的解释比我做得更好,特别是因为他有一些很好的幻灯片来配合它。
TypeScript 完全是编译端;所有静态类型在转换为 JavaScript 时都会丢失。没有什么可以阻止您执行以下操作:
let foo: { myProperty: string } = { myProperty: "g" }; // myProperty is non-nullable
foo["myProperty"] = undefined; // bypass type checker!