关于TypeScript

200 阅读6分钟

为什么用

程序更容易理解

  • 函数或者方法输入和输出的参数类型以及条件。

  • 动态语言的约束只有程序运行起来才能找到报错解决需要手动调试。

  • 有了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 未知类型的值

image.png

image.png

void 表示空

never 表示永远不会返回结果

object

array

image.png

image.png

tuple 元组

enum 枚举

image.png

image.png

类型断言

image.png

非空断言

  • 在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 ! 可以用于断言操作对象是非 null 和非 undefined 类型。

image.png

函数

参数类型声明

函数返回值类型声明

image.png

函数完整类型

    let sum2: (x: number, y: number) => number = function (x: number, y: number): number {
      return x + y
    }

void->没有返回值的函数 never->永远执行不完

image.png

可选参数(可选参数后面不允许再出现必需参数)

    function buildName(firstName: string, lastName?: string) { }

参数默认值

    function buildName2(firstName: string, lastName: string = "1") { }

剩余参数

image.png

函数重载

image.png

promise

image.png

image.png

抽象类

类的访问类型

image.png

类的简便写法

静态类

类的只读属性

接口

image.png

image.png

image.png

image.png

下标类型给数组用

interface Sss{
  [inx:number]: number | string
}
let arrs:Sss = [1,'2']

接口给函数用

interface Sss2{
  //前面是形参 后面是返回值
  (p:string) : void
}
let fn:Sss2 = (p:string) => {};
fn("")

任意属性

image.png

类型别名与接口

都可定义对象和函数

image.png

与接口不同,类型别名还可以用于其他类型,如基本类型(原始值)、联合类型、元组。

image.png

接口可以定义多次 会被自动合并为单个接口,类型别名不可以

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不会经过额外属性检查

image.png

  • 断言

image.png

泛型(定义函数,接口或者类的时候,不先指定类型而是在使用的时候再指定类型)

出现动机

image.png

  • 想传入任何类型的值返回相同类型的值,而any值能满足前者后者不一定满足,变量就丧失了类型。

基操

image.png

image.png

约束(使用 extends 关键字)

image.png

image.png

image.png

  • 此时传入字符串不行,但是想输出字符串长度就要使用约束。使用interface实现约束,如下:

image.png

泛型用到类型别名中

image.png

泛型用到接口中

image.png

image.png

小案例

image.png

image.png

高级类型

type guard

image.png

类型的别名

image.png

联合类型

交叉类型

image.png

image.png

in

image.png

image.png

typeof 操作符可以用来获取一个变量或对象的类型(嵌套也管用)

image.png

  • 使用 typeof 操作符来快速获取配置对象的「形状」

image.png

instanceof(类型保护*是通过构造函数来细化类型的一种方式)

image.png

keyof(用于获取某种类型的所有键,其返回类型是联合类型)

image.png

索引类型

image.png

映射类型

image.png

工具类型

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代码

  1. npm init -y
  1. cnpm i -D webpack webpack-cli typescript ts-loader
  1. 新建webpack.config.js

  1. 新建tsconfig.json

  1. src/index.ts

  1. 修改package.json

  1. npm run build

  1. cnpm i -D html-webpack-plugin(动态打包html插件)
  1. 修改webpack.config.js

  1. cnpm i -D webpack-dev-server(实时监听插件)
  1. 修改package.json

  1. npm run dev

  1. cnpm i -D clean-webpack-plugin(清除打包文件目录)
  1. 修改webpack.config.js

  1. 修改webpack.config.js

  1. cnpm i -D @babel/core @babel/preset-env babel-loader core-js

  1. 打包结果

  • 注意webpack默认打包后是一个立即执行的箭头函数,在IE 11中也是无法执行的!也就是webpack放弃了IE的意思。那么还想去做下挣扎。
  1. 修改webpack.config.js

  1. 打包结果