# 体验 Typescript
# Typescript 工作原理
通过 typescript 命令行工具, 把 typescript 转成 javascript, 从而支持在浏览器运行.
注: 后面的文章中 typescript 简称 ts , javascript 简称js.
# Typescript 特性
ts 和 js 最大的区别就是 ts 多了类型注解功能, 通过名字中的 "type" 也能看出语言的重点在 "类型" 上. 这个类型分为基础类型和高级类型, 高级类型就是通过基础类型组成的自定义类型
# 基础类型
ts 中包含了 boolean / number / string / object / 数组(数组的表示有多种, 后续文章会展开) / 元组 / 枚举 / any / undefined / null / void / never
any 是本文的重点, 一会会对他着重讲解.
补充说明: 上面列出的类型, 是 ts 中表示类型的关键字, 其中 object 其实是包含数组/元祖/枚举, 在 ts 的概念中, 这个叫做类型兼容, 就是说数组类型数据, 也可以用object来标注:
let array: object = [12, 321];
# 高级类型
大部分情况是对 object 类型做更细的标注, 此处不多讲, 先放个例子了解即可, 知道关键词 interface 即可, 中文名 "接口", 后续章节会展开.
interface Article {
title: string;
count: number;
content: string;
tags: string[]; // 数组里的元素都是字符串
}
2
3
4
5
6
# 聪明的 vscode
当我们使用 vscode 编辑器的时候, 编辑器会根据我们的 "类型注解" 进行代码提示和错误提示:
类型写错了, 也会提示:
# 开始实践
- 安装 nodejs (opens new window)
- 在命令行运行
npm i -g typescript
, 安装编译器到全局. - 安装vscode 编辑器 (opens new window).
# 开始写代码
# 生成 js
- 建立一个文件夹, 在里面新建一个 hello.ts 文件, 注意扩展名是 ts.
- 用 vscode 打开 hello.ts 文件.
- 输入如下代码, 让我们体验下 ts:
interface A {
a: number;
b: string;
}
let obj: A = { a: 123, b: "456" };
2
3
4
5
- 命令行进入文件夹, 执行命令
npx tsc hello.ts
好了我们可以看下文件内部多了一个 hello.js , 打开看看:
var obj = { a: 123, b: "456" };
代码中的"类型注解"不见了 ,我们的 ts
被编译成 js
了, 是不是很神奇.
# 错误提示
interface A {
a: number;
b: string;
}
// 错误, 会提示b的类型错误, 应该为string类型
let obj: A = { a: 123, b: 456 };
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”
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";
}
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"
]
}
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