0004. 类型 vs. 值
- 1. 🎯 本节内容
- 2. 🫧 评价
- 3. 🤔 “类型”是什么?
- 4. 🤔 “值”是什么?
- 5. 🤔 在 TypeScript 中,所有值都是有类型的?
- 6. 🤔 什么是“值代码”、“类型代码”?
- 7. 🤔 最终参与运行的代码是“值代码”还是“类型代码”?
- 8. 🤔 “类型代码”有什么用?
- 9. 🤔 是否存在某些业务需求,使用 JS 不能做,必须使用 TS 才能做?
- 10. 🤔 TS 开发的项目比 JS 开发的项目性能更好?
- 11. 🔗 引用
1. 🎯 本节内容
- 类型的概念
- 值的概念
2. 🫧 评价
学习 TypeScript 需要分清楚“值”(value)和“类型”(type),这对加深 JS、TS 之间关系的理解很有帮助。在继续后续内容的学习之前,弄清楚这一点还是很有必要的。
那么“类型”和“值”是什么呢?
- 我们知道 TS 是 JS 的超集,而“类型系统”其实就是 TS 比 JS 多出的那一部分玩意儿。
- “类型的概念”描述起来会比较抽象,往简单了说,类型是用来描述值的,是值的一个特征。
- 比如,把人比作“值”,那么可以提取出一个“性别”特征,好比问你是什么类型 -> 男/女。
- 不同类型的值,具有不同的特征,TS 会为其添加不同的约束,从而保证值的类型安全。
这里可以粗略地给一个结论:文中提到的“值” = 抛弃掉 TS 比 JS 多出的那部分玩意儿(类型信息)后留下的“纯 JS 代码”。
3. 🤔 “类型”是什么?
3.1. 类型(type)
- 类型指的是一组具有相同特征的值。如果两个值具有某种共同的特征,就可以说,它们属于同一种类型。
- 举例来说,
123和456这两个值,共同特征是都能进行数值运算,所以都属于“数值”(number)这个类型。 - 一旦确定某个值的类型,就意味着,这个值具有该类型的所有特征,可以进行该类型的所有运算。凡是适用该类型的地方,都可以使用这个值;凡是不适用该类型的地方,使用这个值都会报错。
- 可以这样理解,类型是人为添加的一种编程约束和用法提示。 主要目的是在软件开发过程中,为编译器和开发工具提供更多的验证和帮助,帮助提高代码质量,减少错误。
3.2. 示例
ts
// 下面是一段简单的 TypeScript 代码,演示一下类型系统的作用
function addOne(n: number) {
return n + 1
}
// 上面示例中,函数 addOne() 有一个参数 n,类型为数值 number
// 表示这个位置只能使用数值 number,传入其他类型的值就会报错
addOne('hello') // ❌ Argument of type 'string' is not assignable to parameter of type 'number'.
// 上面示例中,函数 addOne() 传入了一个字符串 'hello'
// TypeScript 发现类型不对,就报错了
// 指出这个位置只能传入数值,不能传入字符串1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
3.3. 对比 JS
- JavaScript 语言就没有这个功能,不会检查类型对不对。开发阶段很可能发现不了这个问题,代码也许就会原样发布,导致程序在实际运行时遇到错误。
- 作为比较,TypeScript 是在开发阶段报错,这样有利于提早发现错误,避免使用时报错。另一方面,函数定义里面加入类型,具有提示作用,可以告诉开发者这个函数怎么用。
4. 🤔 “值”是什么?
4.1. “值” vs. “类型”
- “类型”是针对“值”的,可以视为是后者的一个元属性。每一个值在 TypeScript 里面都是有类型的。比如,3 是一个值,它的类型是 number。
- TypeScript 代码只涉及类型,不涉及值。所有跟“值”相关的处理,都由 JavaScript 完成。
- 这一点务必牢记。TypeScript 项目里面,其实存在两种代码,一种是底层的“值代码”,另一种是上层的“类型代码”。前者使用 JavaScript 语法,后者使用 TypeScript 的类型语法。
- 它们是可以分离的,TypeScript 的编译过程,实际上就是把“类型代码”全部拿掉,只保留“值代码”。
- 编写 TypeScript 项目时,不要混淆哪些是值代码,哪些是类型代码。
4.2. 示例
ts
function addOne(n: number) {
return n + 1
}
addOne('hello')
// 拿掉“类型代码”之后的“值代码”如下:
function addOne(n) {
return n + 1
}
addOne('hello')1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
4.3. “值代码” vs. “类型代码”

- 黄色部分 -> 值代码
- 蓝色部分 -> 类型代码
5. 🤔 在 TypeScript 中,所有值都是有类型的?
- ✅ 是的
6. 🤔 什么是“值代码”、“类型代码”?
- 这篇笔记中所说的“值代码”是指“JavaScript”,“类型代码”是指“TypeScript”。
- 最终参与运行的是“值代码”而非“类型代码”。
- TypeScript 的编译器 tsc 干的事儿,其实就是把“类型代码”给移除掉,转为“值代码”。
7. 🤔 最终参与运行的代码是“值代码”还是“类型代码”?
- “值代码”,也就是 JavaScript,而非 TypeScript。
- 由此可见,最终决定程序运行逻辑的,是去掉类型信息之后的 JavaScript。
- 因此,绝对不存在什么业务需求,是必须使用 TypeScript 才能实现,而使用 JavaScript 是无法实现的。
8. 🤔 “类型代码”有什么用?
- 既然最终运行的是“值代码” - JavaScript,那么“类型代码” -> TypeScript 有啥用呢?它又不参与最终的运行。
- 这个问题其实就在在问 TypeScript 提供的类型系统有啥用?
- 额,一言难尽……
- 后面慢慢学习,慢慢理解吧,这里可以简单提几点原因:
- 弥补 JavaScript 中类型“随便”的短板,让低级的因类型导致的 bug 尽快在写代码时就暴露出来
- 更友好地 IDE 支持,已获得更好的开发体验
- ……
- 哎呀,总之现在越来越多的 JavaScript 项目选择投入 TypeScript 的怀抱、越来越多的项目使用 TypeScript 来开发,必然是因为 TypeScript 提供了一些我们使用 JavaScript 无法享有的特性,学习 TypeScript 其实也就是在学习这些特性。
9. 🤔 是否存在某些业务需求,使用 JS 不能做,必须使用 TS 才能做?
- 纯属扯淡,再次强调 -> 没有任何业务是必须使用 TS 才能做的,而使用 JS 不能做的……
- 虽说 TS 是 JS 的超集,但它仅仅是扩展了 JS 的类型系统,压根就没有提供啥新的功能。这就意味着,从功能实现上讲,并不存在有什么事儿,是 JS 没法做,有了 TS 之后才可以做的。只是说,有些事儿,使用 TS 做比使用 JS 做体验更好。
- 如果你知道 TypeScript 最终是不会参与最终运行的,就不会问出这个问题了。因为最终运行的依旧是我们的 JavaScript 代码,TypeScript 仅仅在我们写代码时给我们提供更强大的类型约束,避免我们犯一些很 low 的错误,并没有扩展任何 JavaScript 没法做到的业务功能。
10. 🤔 TS 开发的项目比 JS 开发的项目性能更好?
- 纯属扯淡 -> 始终记住一点,最终参与运行的是编译后的 JS,而非 TS。TS 提供的类型信息跟你项目的运行性能无直接关系,最终这些“类型代码”都会被 TS 编译器移除。类型代码决定不了你程序最终的性能,性能优劣最终还得看你的 JS “值代码” 的业务逻辑。
11. 🔗 引用
- TypeScript Types
- typescripttutorial 站点中的一篇介绍 「TS 类型」 的文章