类型定义即是量纲
2019 年阅读的前端项目终于吃上了 TypeScript,群众纷纷反映真香!
我在思考,类型定义对于程序语言来说究竟算是什么呢?我们大家都知道编译型语言类型检查不通过是会编译失败的,返回一个错误信息,那么我们为什么要保证变量类型呢?
我不想先谈那些内存结构啊,指针之类的,我想说的是类型定义就好比物理学里的“量纲”。
我们会说 1 立方米的木头,1 吨的木头,都是可以的。但我们不会说 1 安培的木头,或者 1 摄氏度的木头。因为这些量纲没法衡量木头的多少,或者说即使确实有 1 安培电流通过的木头,表面温度为 1 摄氏度的木头,我们也没法了解它到底意味着什么(能换多少钱,需要多少辆车才能拉动?)。
计算机程序是简单的,每个变量,每个函数,他们都只会做两件事,那就是被写入内存和从内存读取,量纲是他们在内存里分配的形式,u32
和 i64
就是不同的变量,长得不一样,功能也不一样。
JavaScript 是弱类型的语言,它容忍隐式类型转换。但 TypeScript 不允许这样做。我们不能把 string
类型的变量传给一个接受 number
类型参数的函数,就好像我们没法把木头接到灯泡上指望它发光一样(好吧,如果这是一段带点的木头就当我在放屁),尤其是你接到的还是一段看起来很像电池的木头,比如名为 battery
,但类型是 wood
。
另外,保证量纲被定义的好处是我们拥有了更好的接口提示,即使之前就有 document comment,但我们依然只能通过 description 来辨识变量类型和猜测该用的参数,有 TypeScript 以后 ……
最后,我想说的是,即使 TypeScript 给开发过程带来了巨大的便利,但我们仍应该清楚地认识到它只是一门 JavaScript 的预处理语言,运行时仍是那个不带类型检查的玩具语言(?),当 API 接口返回的数据不同于类型定义的 Interface 怎么办?
Runtime Type Check
一种方案是 WebAssembly,在 Rust 代码里用 Serde 之类的序列化工具来整理 JSON 数据,如果遇到不存在的属性会直接报错
另一种就是 JS 方式:invariant
1 | var invariant = require('invariant'); |