# TypeScript 基础

TS是JS的超集,最主要的变化就是引入了Type,对每个变量可以声明类型,类似于其他面向对象语言(java,C#)。

# 安装配置

1
npm i typescript -g
1
tsc xxx.ts 编译为js然后使用node运行

# 类型明确

数据类型 关键字 描述
任意类型 any 声明为 any 的变量可以赋予任意类型的值。
数字类型 number 双精度 64 位浮点值。它可以用来表示整数和分数。
字符串类型 string 一个字符系列,使用单引号()或双引号(")来表示字符串类型。以及模板字符串: let words: string = 您好,今年是 ${ name } 发布 ${ years + 1} 周年 ;` |
布尔类型 boolean 表示逻辑值:true 和 false。
数组类型 声明变量为数组。 // 在元素类型后面加上[] let arr: number[] = [1, 2]; 或者使用数组泛型 let arr: Array<number> = [1, 2];
元组 元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。 let x: [string, number]; x = ['Runoob', 1]; // 运行正常 x = [1, 'Runoob']; // 报错 console.log(x[0]); // 输出 Runoob
枚举 enum 枚举类型用于定义数值集合。 enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 输出 2
void void 用于标识方法返回值的类型,表示该方法没有返回值。 function hello(): void { alert("Hello Runoob"); }
null null 表示对象值缺失。
undefined undefined 用于初始化变量为一个未定义的值
never never never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

# 定义类型

# 简单变量类型

1
2
3
let sum:number = 0;
sum=10;
// sum="a"; --Type 'string' is not assignable to type 'number'.

# 对象类型

1
2
3
4
5
6
7
8
9
10
// 对象的类型
interface Student{
name:string; //规定了Student对象内的字段类型
age:number;
}
let zs:Student = {
name: "张三",
age: 19,
// age: "19", Type 'string' is not assignable to type 'number'.
}

可选属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// {} 指定对象内属性
let student: {name: string, age: number}
student = {name:"张三",age: 19}
student = {name: '李四'} //缺少age属性,报错

//在属性名后面加上 ? ,表示属性是可选的
let teacher: {name: string, age?:number};
teacher = {name:'王老师',age: 29}
teacher = {name:'张老师'} //缺少age属性,但不会报错

//或者使用
let master: {name: string, [other: string]: any}
master = {name:"master",other:"其他随便添加也不会报错",habits: "football"}
console.log(master);


//对于函数
let add = (a:number,b:number) => {
return a+b;
}
console.log(add(2, 3)); // 5

# 枚举类型

1
2
3
4
5
6
7
8
9
10
11
//enum 枚举类型
enum sex{
Male = 1,
Female = 2,
}
let tom = {
name: "Master",
sex: sex.Male, // 根据枚举中对应值,存储的实际上是 1
}
console.log(tom); // { name: 'Master', sex: 1 }

# 组合类型

# 聚合

1
type MyBool = true | false;  //自动归类为boolean

# 泛型

1
2
3
type StringArray = Array<string>;
type NumberArray = Array<number>;
type ObjectWithNameArray = Array<{ name: string }>;

# 类型断言

tips: unknown 类型比 any 类型更安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let a:any;
a=10;
a="str";

let b:unknown;
b=10;
b="str";

let c:string;
c=a; //不会报错,但会把c也变成any类型.
c=b; //会报错, Type 'unknown' is not assignable to type 'string'.

断言:
c = b as String
c = <string>b;

# 编译选项

ts转js的相关配置写在根目录的tsconfig.json中

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
46
47
48
49
50
51
52
53
54
{
/*
tsconfig.json 是ts编译器的配置文件
*/
"compilerOptions": {
//include 表示哪些文件需要被编译

//exclude 不需要编译的 默认值["node_modules","bower_components"]

// 指定编译版本
"target": "ES6",

// 指定模块化的标准
"module": "ES2015",

// 指定使用的库
"lib": ["DOM","ES6"],

// 指定编译后文件所在目录
"outDir": "dist",

// 设置outFile后所有全局作用域中的代码会合并到一个文件
// "outFile": "./dist/app.js"

// 是否编译JS文件
"allowJs": true,

// 是否检查js代码语法规范
"checkJs": false,

// 是否移除注释
"removeComments": true,

// 不生成编译文件
"noEmit": false,

// 不编译有错误的文件
"noEmitOnError": false,

// 总是按照严格模式,默认为false
"alwaysStrict": true,

// 不允许隐式any
"noImplicitAny": false,

// 不允许不明类型的this
"noImplicitThis": true,

// 严格检查空值
"strictNullChecks": false,

// ...
}
}

# 打包配置

使用 webpack 打包

  1. 初始化
  2. 安装对应包工具
  3. 新建配置 webpack.config.js
  4. 新建配置 tsconfig.json
  5. 配置 package.json
  6. 执行 npm run build 开始打包

首先进入项目目录,初始化

npm init -y

然后安装主要包

npm i -D webpack webpack-cli typescript ts-loader

新建 webpack 配置文件 webpack.config.js

image-20230203113422164

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
// webpack.config.js
// 引入路径包
const path = require('path');

// webpack的所有配置都写在 module.exports中
module.exports = {
// 指定入口文件
entry: "./src/index.ts",

// 指定打包文件所在目录
output: {
// 指定打包文件的目录
path: path.resolve(__dirname, "dist"),
// 打包后的文件名
filename: "bundle.js"
},

//指定webpack打包时使用的模块
module:{
// 指定打包的规则
rules: [
{
//test是指定的文件规则
test: /\.ts$/,
use: "ts-loader",
// 排除文件
exclude: /node_modules/
}
]
}
}

新建 TS 配置文件 tsconfig.json

1
2
3
4
5
6
7
{
"compilerOptions": {
"target": "ES2015",
"module": "ES2015",
"strict": true,
}
}

在 webpack 的 package.json 中配置 scripts, 加上一句

“build”: “webpack”

1
2
3
4
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack" //加入这一句,直接运行build打包
},

最后执行 npm run build 进行打包 (这里报了一个 warning)

image-20230203115112069

原因是没有指定 mode, 在 webpack.config.js 中设置

1
2
3
4
5
6
7
8
9
module.exports = {
entry: './src/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
mode: 'development' // 设置mode
}

解决~

image-20230203141229926

# Babel

webpack.config.js 中添加以下 loader 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env"]
}
}
]
}
]
}
}

然后安装相应的依赖:babel-loader、@babel/core、@babel/preset-env:

1
npm install --save-dev babel-loader @babel/core @babel/preset-env

上面是将 babel 的 preset 参数配置在了 webpack.config.js 中,实际上也可以将它按照 babel 配置文件的原则提取出来单独一个 babel.config.json 文件,效果是一样的。

这样就完成了在 webpack 项目中添加 Babel 转换 ES6 + 代码的功能。在 webpack 打包的过程中,会将源代码经由 babel-loader 处理转换为目标代码,这一执行过程对我们来只说是打包时 “顺势而为” 的,我们再也不用关心 Babel 本身的命令细节了。