体验 Typescript

Typescript 工作原理

通过 typescript 命令行工具, 把 typescript 转成 javascript, 从而支持在浏览器运行.

注: 后面的文章中 typescript 简称 ts , javascript 简称js.

Typescript 特性

tsjs 最大的区别就是 ts 多了类型注解功能, 通过名字中的 "type" 也能看出语言的重点在 "类型" 上. 这个类型分为基础类型高级类型, 高级类型就是通过基础类型组成的自定义类型

基础类型

ts 中包含了 boolean / number / string / object / 数组(数组的表示有多种, 后续文章会展开) / 元组 / 枚举 / any / undefined / null / void / never

any 是本文的重点, 一会会对他着重讲解.

补充说明: 上面列出的类型, 是 ts 中表示类型的关键字, 其中 object 其实是包含数组/元祖/枚举, 在 ts 的概念中, 这个叫做类型兼容, 就是说数组类型数据, 也可以用object来标注:

let array: object = [12, 321];
1

高级类型

大部分情况是对 object 类型做更细的标注, 此处不多讲, 先放个例子了解即可, 知道关键词 interface 即可, 中文名 "接口", 后续章节会展开.

interface Article {
    title: string;
    count: number;
    content: string;
    tags: string[]; // 数组里的元素都是字符串
}
1
2
3
4
5
6

聪明的 vscode

当我们使用 vscode 编辑器的时候, 编辑器会根据我们的 "类型注解" 进行代码提示错误提示:

类型写错了, 也会提示:

开始实践

  1. 安装 nodejs
  2. 在命令行运行npm i -g typescript, 安装编译器到全局.
  3. 安装vscode 编辑器.

开始写代码

生成 js

  1. 建立一个文件夹, 在里面新建一个 hello.ts 文件, 注意扩展名是 ts.
  2. vscode 打开 hello.ts 文件.
  3. 输入如下代码, 让我们体验下 ts:
interface A {
    a: number;
    b: string;
}
let obj: A = { a: 123, b: "456" };
1
2
3
4
5
  1. 命令行进入文件夹, 执行命令
npx tsc hello.ts
1

好了我们可以看下文件内部多了一个 hello.js , 打开看看:

var obj = { a: 123, b: "456" };
1

代码中的"类型注解"不见了 ,我们的 ts 被编译成 js 了, 是不是很神奇.

错误提示

interface A {
    a: number;
    b: string;
}
// 错误, 会提示b的类型错误, 应该为string类型
let obj: A = { a: 123, b: 456 };
1
2
3
4
5
6

any 类型

any 代表任意类型, 这个类型特别适合 ts 新手, 初期有些类型不知道如何表达, 我们就可以暂时使用 any 表达, 等熟练 ts 后再标注精准的类型.

下面的情况新手可能就不会了, 以为 n 标记为 number, 但是循环中 i 大于 5 的时候就是字符串了, 所以 ts 就会提示错误.

let n: number;
for (let i = 0; i < 10; i++) {
    if (i <= 5) n = 10;
    else n = "100";
}
// ts提示: 不能将类型“"100"”分配给类型“number”
1
2
3
4
5
6

作为新手如果初期你不知道"联合类型"这个概念, 你就可以直接把 n 标记为 any

// 熟练后会是这么标记的
// let n:string|number
let n: any;
for (let i = 0; i < 10; i++) {
    if (i <= 5) n = 10;
    else n = "100";
}
1
2
3
4
5
6
7

补充

Typescript的配置文件 —— tsconfig.json 放在你项目的根目录即可:

// tsconfig.json仅供参考
{
    "compilerOptions": {
        // 不报告执行不到的代码错误。
        "allowUnreachableCode": true,
        // 必须标注为null类型,才可以赋值为null
        "strictNullChecks": true,
        // 严格模式, 强烈建议开启
        "strict": true,
        // 支持别名导入:
        // import * as React from "react"
        "esModuleInterop": true,
        // 目标js的版本
        "target": "es5",
        // 目标代码的模块结构版本
        "module": "es6",
        // 在表达式和声明上有隐含的 any类型时报错。
        "noImplicitAny": true,
        // 删除注释
        "removeComments": true,
        // 保留 const和 enum声明
        "preserveConstEnums": false,
        // 生成sourceMap
        "sourceMap": true,
        // 目标文件所在路径
        "outDir": "./lib",
        // 编译过程中需要引入的库文件的列表
        "lib": [
            "dom",
            "es7"
        ],
        // 额外支持解构/forof等功能
        "downlevelIteration": true,
        // 是否生成声明文件
        "declaration": true,
        // 声明文件路径
        "declarationDir": "./lib",
        // 此处设置为node,才能解析import xx from 'xx'
        "moduleResolution": "node"
    },
    // 入口文件
    "include": [
        "src/main.ts"
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45