为什么用
程序更容易理解
-
函数或者方法输入和输出的参数类型以及条件。
-
动态语言的约束只有程序运行起来才能找到报错解决需要手动调试。
-
有了Typescript,代码本身即可回答上述问题,不需要去猜测。
效率更高
-
代码自动补全
-
丰富的接口提示
更少的错误
-
编译期间能够发现大部分错误
-
杜绝一些比较常见的低级错误
包容性
-
完全兼容js
-
第三方库可以单独编写类型文件
缺点
-
有些学习成本
-
短期内增加有些开发成本
安装使用
npm install typescript -g
demo
方案一:终端输入tsc 1.js转化 (tsc -> typescript compiler)
- 如果报错
1.终端输入set-ExecutionPolicy RemoteSigned
2.再次执行tsc 1.js
- 结果
方案二:ts-node解决编译
-
npm install -g ts-node
-
ts-node 1.ts
方案三:(浏览器沙盒操作) www.typescriptlang.org/play?#code/…
基本类型
number
string
boolean
any 任意类型
unknown 未知类型的值
void 表示空
never 表示永远不会返回结果
object
array
tuple 元组
enum 枚举
类型断言
非空断言
- 在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 ! 可以用于断言操作对象是非 null 和非 undefined 类型。
函数
参数类型声明
函数返回值类型声明
函数完整类型
let sum2: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y
}
void->没有返回值的函数 never->永远执行不完
可选参数(可选参数后面不允许再出现必需参数)
function buildName(firstName: string, lastName?: string) { }
参数默认值
function buildName2(firstName: string, lastName: string = "1") { }
剩余参数
函数重载
promise
类
抽象类
类的访问类型
类的简便写法
静态类
类的只读属性
接口
下标类型给数组用
interface Sss{
[inx:number]: number | string
}
let arrs:Sss = [1,'2']
接口给函数用
interface Sss2{
//前面是形参 后面是返回值
(p:string) : void
}
let fn:Sss2 = (p:string) => {};
fn("")
任意属性
类型别名与接口
都可定义对象和函数
与接口不同,类型别名还可以用于其他类型,如基本类型(原始值)、联合类型、元组。
接口可以定义多次 会被自动合并为单个接口,类型别名不可以
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
接口的扩展就是继承 类型别名的扩展就是交叉类型
接口扩展接口
interface PointX {
x: number
}
interface Point extends PointX {
y: number
}
类型别名拓展类型别名
type PointY = {
x: number
}
type Point6 = PointX & {y: number}
接口拓展类型别名
type PointXX = {
x: number
}
interface Point extends PointX {
y: number
}
类型别名拓展接口
interface PointX {
x: number
}
type Point33 = PointX & {
y: number
}
绕开额外属性检查的方式
- 在参数里写对象就相当于是直接给labeledObj赋值,这个对象有严格的类型定义,所以不能多参或少参。而当你在外面将该对象用另一个变量myObj接收,myObj不会经过额外属性检查
- 断言
泛型(定义函数,接口或者类的时候,不先指定类型而是在使用的时候再指定类型)
出现动机
- 想传入任何类型的值返回相同类型的值,而any值能满足前者后者不一定满足,变量就丧失了类型。
基操
约束(使用 extends 关键字)
- 此时传入字符串不行,但是想输出字符串长度就要使用约束。使用interface实现约束,如下:
泛型用到类型别名中
泛型用到接口中
小案例
高级类型
type guard
类型的别名
联合类型
交叉类型
in
typeof 操作符可以用来获取一个变量或对象的类型(嵌套也管用)
- 使用 typeof 操作符来快速获取配置对象的「形状」
instanceof(类型保护*是通过构造函数来细化类型的一种方式)
keyof(用于获取某种类型的所有键,其返回类型是联合类型)
索引类型
映射类型
工具类型
Partial 将类型的属性变成可选 只支持处理第一层的属性
type Partial<T> = {
[P in keyof T]?: T[P];
};
//使用
interface UserInfo {
id: string;
name: string;
}
type NewUserInfo = Partial<UserInfo>;
const xiaoming: NewUserInfo = {
name: 'xiaoming'
}
DeepPartial 支持处理所有层的属性
type DeepPartial<T> = {
[U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U]
};
Required将类型的属性变成必选
// 原理
type Required<T> = {
[P in keyof T]-?: T[P]
};
Readonly 的作用是将某个类型所有属性变为只读属性
// 原理
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
Pick 从某个类型中挑出一些属性出来
// 原理
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
Record的作用是将 K 中所有的属性的值转化为 T 类型。
// 原理
type Record<K extends keyof any, T> = {
[P in K]: T;
};
interface PageInfo {
title: string;
}
type Page = "home" | "about" | "contact";
const x: Record<Page, PageInfo> = {
about: { title: "about" },
contact: { title: "contact" },
home: { title: "home" },
};
ReturnType 用来得到一个函数的返回值类型
type Func2 = (value: number) => string;
const foo22: ReturnType<Func2> = "1";
// ReturnType获取到 Func 的返回值类型为 string,所以,foo 也就只能被赋值为字符串了。
Exclude<T, U> 的作用是将某个类型中属于另一个的类型移除掉。
// 原理
type Exclude<T, U> = T extends U ? never : T;//将 T 中某些属于 U 的类型移除掉。
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number
Extract<T, U> 的作用是从 T 中提取出 U。
// 原理
type Extract<T, U> = T extends U ? T : never;
type T01 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T11 = Extract<string | number | (() => void), Function>; // () =>void
Omit<T, K extends keyof any> 的作用是使用 T 类型中除了 K 类型的所有属性,来构造一个新的类型。
// 原理
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview2 = Omit<Todo, "description">;
const todo66: TodoPreview = {
title: "Clean room",
completed: false,
};
NonNullable 的作用是用来过滤类型中的 null 及 undefined 类型。
// 原理
type NonNullable<T> = T extends null | undefined ? never : T;
type T02 = NonNullable<string | number | undefined>; // string | number
type T12 = NonNullable<string[] | null | undefined>; // string[]
Parameters 的作用是用于获得函数的参数类型组成的元组类型。
type A = Parameters<() =>void>; // []
type B = Parameters<typeof Array.isArray>; // [any]
type C = Parameters<typeof parseInt>; // [string, (number | undefined)?]
type D = Parameters<typeof Math.max>; // number[]
编译选项
1.新建tsconfig.json
2.终端输入tsc 自动编译所有ts文件为Js
3.终端输入tsc -w 监控所有ts文件修改更新
4.tsconfig.json
webpack打包ts代码
- npm init -y
- cnpm i -D webpack webpack-cli typescript ts-loader
- 新建webpack.config.js
- 新建tsconfig.json
- src/index.ts
- 修改package.json
- npm run build
- cnpm i -D html-webpack-plugin(动态打包html插件)
- 修改webpack.config.js
- cnpm i -D webpack-dev-server(实时监听插件)
- 修改package.json
- npm run dev
- cnpm i -D clean-webpack-plugin(清除打包文件目录)
- 修改webpack.config.js
- 修改webpack.config.js
- cnpm i -D @babel/core @babel/preset-env babel-loader core-js
- 打包结果
- 注意webpack默认打包后是一个立即执行的箭头函数,在IE 11中也是无法执行的!也就是webpack放弃了IE的意思。那么还想去做下挣扎。
- 修改webpack.config.js
- 打包结果