1. TypeScript
- 简单介绍
- 以JavaScript为基础构建的语言
- 一个JavaScript的超集
- 可以在任何支持JavaScript的平台执行
- TypeScript扩展了JavaScript并添加了类型
1.1 TypeScript的基本安装使用
- 安装node.js
- 使用npm全局安装TypeScript
- npm install -g typescript
- 创建一个.ts文件
- 比如新建一个helloTS.ts文件,编写内部的逻辑
- 使用tsc对当前新建的ts文件进行编译
- 使用终端运行 tcs helloTS.ts 这个文件后就会编译出helloTS.js文件
1.2 TypeScript的基本类型
类型 | 描述 |
---|---|
number | 任意数字 |
boolean | 布尔值true和false |
string | 任意字符串 |
字面量 | 限制变量的值就是该字面量的值 |
any | 任意类型 |
unknown | 类型安全的any |
void | 没有值(或undefined) |
never | 不能是任何值 |
object | 任意的js对象 |
array | 任意js数组 |
tuple | 元素,表示一个已知元素数量和类型的数组,各元素的类型不必相等 |
enum | 枚举 |
1.2.1 number类型
- 和JavaScript一样,TypeScript里的所有数字都是浮点数。这些浮点数的类型是number,除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript2015中引入的二进制和八进制字面量
- 代码练习
// 定义变量为number类型,同时又初始化赋值
let num1: number = 111
let num2: number = 0xf00d
let num3: number = 0b1010
let num4: number = 0o744
// 定义了变量的类型是number类型
let num5: number
num5 = 789
// 通过字面量的方式定义变量的值, 变量的值只能是字面量定义的初始值
let num6: 123
num6 = 123
1.2.2 布尔值
- 最基本数据类型 true/false值
- 代码练习
// 初始化
let isShow: boolean = false
isShow = true
let isLoading: boolean
isLoading = false
isLoading = true
// 字面量方式定义时,设置为boolean类型的false值,使用时不能更改为true
let isShowToast: false
isShowToast = false
1.2.3 字符串类型
- 和JavaScript一样,可以使用单引或双引,也可以使用模板字符串
- 代码练习
// 初始化
let str1: string = 'hello'
str1 = 'world'
let str2: string
str2 = 'hello TS...'
// 使用模板字符串
let username: string = "wukong"
let count: number = 123
let str3: string = `excuse, Are you ${username} ? `
1.2.4 联合类型
- 可以使用 | 来链接多个类型
- 代码练习
let sex: "male" | "female";
sex = "male";
sex = "female";
// 使用 | 链接多个类型
let list: string | boolean | number
list = "hello"
list = true
list = 123
1.2.5 any
- 表示可以是任意类型,将一个变量设置为any类型后,相当于对该变量关闭了TS的类型检查
- 当变量是any类型时,赋值给任何类型的变量不会报错
- 代码练习
let noSure: any;
// 声明变量不指定类型,则TS解析器会自动判断类型为any (隐式的any)
let yesSure;
noSure = 1;
noSure = false;
noSure = "123";
noSure = [1, 2, 3];
yesSure = 1;
yesSure = true;
yesSure = "123";
yesSure = [1, 2, 3];
1.2.6 unknown
- 当声明变量类型是unknown时,相当于是一个类型安全的any.unknown声明的变量不能直接赋值给其他变量
- 代码练习
let e: unknown
e = 123
e = true
// 如果不对变量e不做类型检查直接赋值给square时,会出错
if( typeof(e) == "string"){
square = e
}
1.2.7 类型断言
- 当我们清楚地知道一个实体具有比它现有类型更确切的类型时,可以通过类型断言这种方式告诉编译器。
- 类型断言有两种形式,其一是"尖括号"语法,另一个为as语法
- 代码练习
// 第一种写法 使用尖括号告诉编译器实际的类型
let someValue: unknown = "this is string";
let strLength: number = (<string>someValue).length;
// 第二种写法 使用as语法实际的类型
let someValue2: unknown;
someValue2 = "this is string...";
let strLength2: number;
strLength2 = (someValue2 as string).length;
1.2.8 Void
- 在某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。当一个函数没有返回值时,通常返回值类型时void.
- 声明一个void类型的变量没有什么大用,因为只能为它赋值undefined和null 3.代码练习
function fn(num: unknown) {
if (typeof num == "number") {
return 123;
} else {
return "123";
}
}
// void用来表示空,以函数为例,就表示没有返回值的函数
function fn1():void {}
// 当返回值是null或undefined
function fn3(): void {
return undefined;
}
// 声明一个void类型的变量
let enable: void
enable = undefined
- Null和Undefined
- TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。和
void
相似,他们的本身的类型用处不是很大: - 默认情况下
null
和undefined
是所有类型的子类型。就是说可以把null
和undefined
赋值给number
类型的变量. - 当指定了
--strictNullChecks
标记,null
和undefined
只能赋值给void
和他们各自。
1.2.9 Never
never
类型表示的是那些用不存在的值的类型,例如抛出异常或根本就不会有返回值never
类型是任何类型的子类型,也可以赋值给任何类型。即使any
也不可以赋值给never
- 代码练习
function fn4(): never{
throw new Error('程序挂了')
}
1.2.10 Object
- object表示非原始类型。
- 声明对象、函数的语法
// 声明a的类型为对象,添加一个属性
let a: { name: string };
a = { name: "sunwuxong" };
// 声明b的类型为对象,添加可选属性age,通过?的形式表示可选属性
let b: { name: string; age?: number };
b = { name: "ershixion" };
// 声明c的类型为对象,添加任意属性
let c: { name: string; [propName: string]: any };
c = { name: "shashidi", gender: "female" };
// 使用箭头函数的形式来声明函数的结构
let d: (a: number, b: number) => number;
d = function (n1: number, n2: number) {
return n1 + n2;
};
1.2.11 Array
- TypeScript像JavaScript一样可以操作数组元素.有两种方式可以定义数组。
- 第一种,可以在元素类型后面接上[],表示由此类型元素组成的一个数组
- 第二种,使用数组泛型, Array<元素类型>
- 代码练习
// 第一种方式定义数组
let arr1: number[]
arr1 = [1,2,3,4]
// 第二种方式定义数组
let arr2: Array<string>
arr2 = ['1','2','3']
1.2.12 元组Tuple
- 元组类型允许表示一个已知元素数量和类型的数组,个元素的类型不必相同。
// 声明元组tuple
let arr3: [ string, boolean ]
arr3 = ["abc", false]
// 访问一个已知索引的元素
console.log(arr3[0].substr(1));
console.log(arr3[1] == false);
1.2.13 枚举enum
- enum类型是对JavaScript标准数据类型的一个补充。可将一个个可读的属性列举出来
- 代码练习
// 声明enum类型
enum Gender {
Mail = 0,
Female = 1,
Other = 2,
}
// 声明对象
let i: { name: string; gender: Gender };
i = { name: "xunwuxong", gender: Gender.Female };
console.log(i.gender === Gender.Female);
- 类型的别名,比如说这样使用
// 类型的别名
type myType = 1 | 2 | 3 | 4 | 5
let user: myType
let person: myType
user = 4
person = 1
2. 编译选项
2.1 自动编译文件
- 编译文件时,使用-w指令后,TS编译器会自动监视文件的变化,并在文件发送变化时对文件进行重新编译。
- 例如: tsc xxx.ts -w
2.2 自动编译整个项目
- 如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件(但是能直接使用tsc命令的前提是,需要在项目根目录下创建一个ts的配置文件tsconfig.json)
- tsconfig.json是一个JSON文件,添加配置文件后,只需要tsc命令即可完成对整个项目的编译
- 在tsconfig.json中的配置选项
2.2.1 include和exclude 配置项
1.include用来指定那些ts文件需要被编译
- * :匹配0或多个字符(表示任意文件)
- ** : 匹配任意子目录
- ? : 匹配一个任意字符
2. exclude用来指定那些ts文件不需要被编译
{
"include": [
"./src/**/*"
],
"exclude": [ "node_modules", "**/*.spec.ts" ]
}
2.2.2 extends和files配置选项
- tsconfig.json文件可以利用extends属性从另一个配置文件里继承配置。
- files: 指定一个包含相对路径或绝对文件路径的列表。
"files": [
"core.ts",
"sys.ts"
],
"extends": "./configs/base",
- configs/base.json
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
}
}
2.2.3 compilerOptions配置选项
- 编译选项是配置文件中非常重要也比较复杂的配置选项
- compilerOptions中包含多个子选项,用来完成对编译的配置
- 编译选项
- target :指定ECMAScript目标版本,默认是ES3,可以设置
"ES5"
,"ES6"
/"ES2015"
,"ES2016"
,"ES2017"
或"ESNext"
。 - module : 指定生成那个模块系统代码。可以设置的值有"CommonJS", "AMD", "System", "UMD", "ES6", "ES2015", "ES2020", "ESNext", "None", "ES2022"
- lib : 编译过程中需要引入的库文件列表,如果
lib
没有指定默认注入的库的列表。默认注入的库为:- 针对于
--target ES5
:DOM,ES5,ScriptHost
- 针对于
--target ES6
:DOM,ES6,DOM.Iterable,ScriptHost
- 针对于
- outdir : 重定向输出目录,编译后的.js文件存放目录
- outFile : 将输出文件合并为一个文件。
- allowJs : 允许编译JavaScript文件,默认为false,不允许编译.js文件
- checkJs : 在.js文件中报告错误。(检查js代码是否规范)与--allowJs配合使用
- removeComments : 删除所有注释。
- noEmit : 不生成输出文件
- noEimtOnError : 报错时不生成输出文件
- target :指定ECMAScript目标版本,默认是ES3,可以设置
{
"compilerOptions": {
"target": "ES6",
"module": "AMD",
"lib": ["es6", "DOM"],
"outDir": "./dist",
"allowJs": true,
"checkJs": true,
"removeComments": true,
"noEmit": false,
"noEmitOnError": true
},
"include": [
"./src/**/*"
],
"exclude": [
"./src/hello/**/*"
]
}
2.3 语法检查
- 在.js文件的开头加入 "use strict",表示.js文件是用严格模式来检查语法
- 在
tsconfig.json
中compilerOptions配置- alwaysStrict : 以严格模式解析并为每个源文件生成"use strict"语句
- noImplicitAny : 在表达式和声明上有隐含的any类型时报错。
- noImplicitThis : 当this表达式的值为any类型的时候,生成一个错误
- strict : 启用所有严格类型检查选项
3. 使用webpack打包ts代码
3.1 打包ts步骤
- 使用npm init对当前项目进行初始化
- 安装webpack所需的依赖
- npm install -D webpack@5.6.0
- npm install -D webpack-cli@4.2.0
- npm install -D typescript@4.1.2
- npm install -D ts-loader@8.0.11
- 在项目目录下新建文件夹src新建在 src下新建index.ts文件,项目根目录下新建webpack.config.js文件、tsconfig.json文件
// src/index.ts
function sum(a: number, b: number) {
return a + b;
}
console.log(sum(2, 4));
// tsconfig.json文件
{
"compilerOptions": {
"target": "ES2015",
"module": "ES2015",
"strict": true
},
"include": [
"src/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
// webpack打包配置文件 webpack.config.js
const path = requier("path")
module.export = {
entry: "./src/index.ts",
output:{
path: path.resolve(__dirname,"dist"),
filename: bundle.js
},
module: {
rules: [
test: /\.ts$/,
use: 'ts-loader'
exclude: /node_modules/
]
}
}
- 最后使用npm run xxx 命令打包ts代码
3.2 优化打包ts代码
- 安装html-webpack-plugin插件,自动生成html代码
npm install -D html-webpack-plugin@4.5.0
- 安装webpack-dev-server,用于配置自动启动浏览器实时打包代码 `npm install -D webpack-dev-server@3.11.0
- 安装clean-webapck-plugin插件,每次编译前把生成的dist目录文件清空
npm install -D clean-webpack-plugin@4.0.0
- 在webpack.config.js中配置resolve,设置引用模块
- 在webpack.config.js的配置文件
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
plugins: [
new htmlWebpackPlugin({
title: "my app",
filename: "index.html",
template: "./src/index.html",
}),
new CleanWebpackPlugin(),
],
// 用来设置引用模块
resolve: {
extensions: [".js", ".ts"],
},
};
3.3 使用Babel,对旧浏览器做兼容性处理,支持es5以下的语法支持
- 需要安装的插件有 @babel/core@7.12.9 @babel/preset-env@7.12.7 babel-loader@8.2.2 core-js@3.8.0
npm install --save-dev @babel/core@7.12.9
npm install --save-dev @babel/preset-env@7.12.7
npm install babel-loader@8.2.2 --save-dev
npm install core-js@3.8.0 --save-dev
- 在webpack.config.js配置babel
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "production",
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.ts$/,
use: [
// 配置Babel
{
// 指定加载器
loader: "babel-loader",
// 设置babel
options: {
// 设置预定于的环境
presets: [
[
// 指定环境插件
"@babel/preset-env",
// 配置信息
{
targets: {
edge: "12",
firefox: "60",
chrome: "60",
safari: "11.1",
ie: "11",
},
// 使用corejs的方式, usage表示按需加载
useBuiltIns: "usage",
// 指定corejs的版本
corejs: "3",
},
],
],
},
},
"ts-loader",
],
exclude: /node_modules/,
},
],
},
plugins: [
new htmlWebpackPlugin({
title: "my app",
filename: "index.html",
template: "./src/index.html",
}),
new CleanWebpackPlugin(),
],
// 用来设置引用模块
resolve: {
extensions: [".js", ".ts"],
},
};