简介 · TypeScript 入门教程

    1. 什么是 TypeScript?
      1. 官方定义:Typed JavaScript at Any Scale.
      2. 添加了类型系统的 js,适用于任何规模的项目。
    2. 从 TypeScript 的名字就可以看出来,「类型」是其最核心的特性。
    3. js 是一门非常灵活的编程语言,以下这些特点,你既可以将其视作是 js 的优点(灵活),也可以将其视作是 js 的缺点(随便)
      1. 它没有类型约束,一个变量可能初始化时是字符串,过一会儿又被赋值为数字。
      2. 由于隐式类型转换的存在,有的变量的类型很难在运行前就确定。
      3. ……
    4. ts 的类型系统,在很大程度上弥补了 js 在类型上表现得很“随便”的缺点
    5. 类型系统按照「类型检查的时机」来分类,可以分为动态类型和静态类型
      1. 动态类型:在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。
      2. 静态类型:编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。
    6. js 是一门动态的解释型语言,没有编译阶段
    7. ts 是一门静态的编译型语言,在运行前需要先编译为 js,而在编译阶段就会进行类型检查
    1. // js
    2. let foo = 1;
    3. foo.split(' ');

    运行时报错:Uncaught TypeError: foo.split is not a function

    在 js 中,上述写法会在运行时会报错(foo.split 不是一个函数),造成线上 bug。

    思考:这种写法,为什么 js 没法在运行之前就给我们报错呢?
    因为在 js 中,对于变量类型的约束是很随便的,这就意味着,从声明变量 foo let foo = 1; 到调用 foo 身上的 split 方法 foo.split(' '); 之间,我们可以随便去变更 foo 的类型。

    1. let foo = 1;
    2. foo = '1';
    3. foo.split(' ');

    foo = '1'; 这种中途变更变量类型的做法,在 js 中是被允许的,所以 js 没法确定当执行 foo.split(' ') 时并能确定它是数字类型。而这种中途变更类型的做法,在 ts 中默认是不被允许的行为,所以 ts 中会及时报错。

    1. // ts
    2. let foo = 1; // let foo: number = 1;
    3. foo.split(' ');

    运行前报错:Property ‘split’ does not exist on type ‘number’.

    在 ts 中,这种写法编译时(在运行代码之前)就会报错(数字没有 split 方法),无法通过编译。

    let foo = 1; 不去手动声明变量 foo 的类型,也能在变量初始化时自动推论出它是一个 number 类型。这得益于 ts 强大的类型推导机制,也就是说这种写法其实等效于 let foo: number = 1;

    1. ts 强大的“类型推论”,使得大部分 js 代码都只需要经过少量的修改(或者完全不用修改)就变成 ts 代码
    2. 类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型
      1. 弱类型:允许隐式类型转换
      2. 强类型:不允许隐式类型转换
    3. js 和 ts 都是弱类型
    4. Python 是强类型

    弱类型:

    1. // js 或 ts
    2. console.log(1 + '1');
    3. // 打印出字符串 '11'

    强类型:

    1. print(1 + '1')
    2. # TypeError: unsupported operand type(s) for +: 'int' and 'str'
    3. # 若要修复该错误,需要进行强制类型转换
    4. print(str(1) + '1')
    5. # 打印出字符串 '11'
    1. ts 的类型系统体现了它的核心设计理念:在完整保留 js 运行时行为的基础上,通过引入静态类型系统来提高代码的可维护性,减少可能出现的 bug
    2. 大型项目 vs. 中小型项目
      1. 大型项目:适合 ts
      2. 中小型项目:适合 js(其实也适合 ts)
    3. ts 非常适用于大型项目——这是显而易见的,类型系统可以为大型项目带来更高的可维护性,以及更少的 bug
    4. 在中小型项目中推行 ts 的最大障碍就是认为使用 ts 需要写额外的代码,降低开发效率。但事实上,由于有类型推论,大部分类型都不需要手动声明了。相反,ts 增强了编辑器(IDE)的功能,包括代码补全、接口提示、跳转到定义、代码重构等,这在很大程度上提高了开发效率。而且 ts 有近百个编译选项,如果你认为类型检查过于严格,那么可以通过修改编译选项来降低类型检查的标准。
    5. ts 还可以和 js 共存。这意味着如果你有一个使用 js 开发的旧项目,又想使用 ts 的特性,那么你不需要急着把整个项目都迁移到 ts,你可以使用 ts 编写新文件,然后在后续更迭中逐步迁移旧文件。如果一些 js 文件的迁移成本太高,ts 也提供了一个方案,你可以在不修改 js 文件的前提下,编写一个类型声明文件,实现旧项目的渐进式迁移
    6. 事实上,就算你从来没学习过 ts,你也可能已经在不知不觉中使用到了 ts —— 在 VSCode 编辑器中编写 js 时,代码补全和接口提示等功能就是通过 TypeScript Language Service 实现的
      image.png
    7. 一些第三方库原生支持了 ts,在使用时就能获得代码补全了,比如 Vue 3.0
      image.png
    8. 有一些第三方库原生不支持 ts,但是可以通过安装社区维护的类型声明库(比如通过运行 npm install --save-dev @types/react 来安装 React 的类型声明库)来获得代码补全能力——不管是在 js 项目中还是在 ts 中项目中都是支持的:
      image.png
    9. ts 的发展已经深入到前端社区的方方面面了,任何规模的项目都或多或少得到了 ts 的支持
    10. ts 是添加了类型系统的 js,适用于任何规模的项目。
    11. ts 是一门静态类型、弱类型的语言。
    12. ts 是完全兼容 js 的,它不会修改 js 运行时的特性。
    13. ts 可以编译为 js,然后运行在浏览器、Node.js 等任何能运行 js 的环境中。
    14. ts 拥有很多编译选项,类型检查的严格程度由你决定。
    15. ts 可以和 js 共存,这意味着 js 项目能够渐进式的迁移到 ts。
    16. ts 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
    17. ts 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
    18. ts 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。
    19. ts 只会在编译时对类型进行静态检查,如果发现有错误,编译的时候就会报错
    20. **noEmitOnError**
      1. **noEmitOnError** 默认值是 **false**,这意味着在 ts 编译的时候即使报错了,还是会生成编译结果
      2. 如果要在报错的时候终止 js 文件的生成,可以在 **tsconfig.json** 中配置 **noEmitOnError****true** 即可