TS笔记
总览
Typescript笔记总结
# TS运行环境和配置(1)
# 全局安装
npm install typescript -g
# 查看版本
tsc --version
tsc 文件名 编译ts文件将其转换为js
tsc 文件名 -w 自动检测实时编译
tsc 编译全部ts文件
# 安装ts-node和其依赖
npm install ts-node -g npm install tslib @types/node -g
# 通过ts-node运行ts代码
ts-node xxx.ts
2
3
4
5
6
7
8
9
10
11
12
13
# TS演练场(2)
TypeScript: 演练场 - 一个用于 TypeScript 和 JavaScript 的在线编辑器 (typescriptlang.org) (opens new window)
# TS数据类型(3)
let str: string = "rio;
let num: number = 24;
let bool: boolean = false;
let u: undefined = undefined;
let n: null = null;
let big: bigint = 100n;
let sym: symbol = Symbol("me");
// 对象类型
let obj: object
obj = { name: 'TypeScript' }
// 数组类型
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
// void类型 通常用来指定一个函数没有返回值
function fnvoid():void{ return undefined }
// any类型 表示不限制标识符的任意类型
const infos: any[] = ["abc", 123, {}, []]
// unknown类型 类似any类型但默认情况下在上面进行任意的操作都是非法的
let arr:unknown = ['a', true, 123]
console.log(arr.length); // 报错
// never类型 表示永远不会发生值
function err():never { throw new Error(); }
function handleMessage(message: string | number | boolean) {
switch (typeof message) {
case "string":
console.log(message.length)
break
case "number":
console.log(message)
break
case "boolean":
console.log(Number(message))
break
default:
const check: never = message
}
}
// tuple元组类型 元组数据结构中可以存放不同的数据类型
const info3: [string, number, number] = ["why", 18, 1.88]
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
# 联合类型与交叉类型(4)
- 联合类型表示多个类型中一个即可
- 交叉类似表示需要满足多个类型的条件
// 联合类型的基本使用
let foo: number | string = "abc"
foo = 123
----------------------
let arr:(number | string)[];
arr = [1, 'b', 2, 'c'];
type NewType = number & string // 没有意义
// 无法同时满足一个number又是一个string的值 所以MyType其实是一个never类型;
interface P {
name: string
age: number
}
interface S {
name: string
coding: () => void
}
type InfoType = P & S
const info: InfoType = {
name: "rio",
age: 18,
coding: function() {
console.log("hello")
}
}
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
# 类型断言(5)
有时候TypeScript无法获取具体的类型信息,这个我们需要使用类型断言
// DOM元素 <img class="img"/>
// 使用类型断言
const imgEl = document.querySelector(".img") as HTMLImageElement
imgEl.src = "xxx"
imgEl.alt = "yyy"
2
3
4
5
# 非空类型断言(5.1)
// 因为传入的mes有可能是为undefined的,这个时候是不能执行方法的
function print(mes:string) {
console.log(mes!.toUpperCase());
}
2
3
4
但是,我们确定传入的参数是有值的,这个时候我们可以使用非空类型断言: 非空断言使用的是 ! ,表示可以确定某个标识符是有值的,跳过ts在编译阶段对它的检测
# 类型别名和接口(6)
type类型使用范围更广, 接口类型只能用来声明对象
- interface 可以重复的对某个接口来定义属性和方法;支持继承;可以被类实现
- type定义的是别名,别名是不能重复的;
type PointType = { x: number, y: number, z?: number }
interface PointType2 {
x: number
y: number
z?: number
}
function printCoordinate(point: PointType) {
console.log(point.x, point.y, point.z)
}
function printCoordinate(point: PointType2) {}
2
3
4
5
6
7
8
9
10
11
12
# 字面量类型(7)
TS支持将一个字面量当成一个类型使用。
type Direction = "left" | "right" | "up" | "down"
const d1: Direction = "left"
-----------------------------------
type MethodType = "get" | "post"
function request(url: string, method: MethodType) {}
// const info = {
// url: "xxxx",
// method: "post"
// }
// 下面的做法是错误: info.method获取的是string类型
// request(info.url, info.method)
// 解决方案一: info.method进行类型断言
// request(info.url, info.method as "post")
// 解决方案二: 直接让info对象类型是一个字面量类型
// const info2: { url: string, method: "post" } = {
// url: "xxxx",
// method: "post"
// }
const info2 = {
url: "xxxx",
method: "post"
} as const
request(info2.url, info2.method)
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
# as const(7.1)
as const
修饰符还可以用来修改对象字面量和数组字面量的类型推断。在这种情况下,as const
会强制 TypeScript 将对象字面量或数组字面量的类型推断为不可变的,即使没有显式地指定类型。这意味着,如果你尝试对变量或表达式进行修改,TypeScript 会报错。
const foo = ['a', 'b'] as const; // 等价于 const foo: ['a', 'b'] = ['a', 'b']
foo.push('c'); // TypeScript 会报错,因为 foo 类型被声明为不可变的
const bar = { x: 1, y: 2 } as const; // 等价于 const bar: { x: 1, y: 2 } = { x: 1, y: 2 }
bar.x = 3; // TypeScript 会报错,因为 bar 类型被声明为不可变的
2
3
4
# 类型缩小(8)
缩小比声明时更小的类型,这个过程称之为 缩小( Narrowing )
- typeof
- 平等缩小(比如===、!==)
- instanceof
- in
// 1.typeof: 使用的最多
function printID(id: number | string) {
if (typeof id === "string") {
console.log(id.length, id.split(" "))
} else {
console.log(id)
}
}
// 2.===/!==: 方向的类型判断
type Direction = "left" | "right" | "up" | "down"
function switchDirection(direction: Direction) {
if (direction === "left") {
console.log("左:", "角色向左移动")
} else if (direction === "right") {
console.log("右:", "角色向右移动")
} else if (direction === "up") {
console.log("上:", "角色向上移动")
} else if (direction === "down") {
console.log("下:", "角色向下移动")
}
}
// 3. instanceof: 传入一个日期, 打印日期
function printDate(date: string | Date) {
if (date instanceof Date) {
console.log(date.getTime())
} else {
console.log(date)
}
// if (typeof date === "string") {
// console.log(date)
// } else {
// console.log(date.getTime())
// }
}
// 4.in: 判断是否有某一个属性
interface ISwim {
swim: () => void
}
interface IRun {
run: () => void
}
function move(animal: ISwim | IRun) {
if ("swim" in animal) {
animal.swim()
} else if ("run" in animal) {
animal.run()
}
}
const fish: ISwim = {
swim: function() {}
}
const dog: IRun = {
run: function() {}
}
move(fish)
move(dog)
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 函数的类型(9)
函数类型的定义包括对参数和返回值的类型定义:
function add1(arg1: number, arg2: number): number {
return arg1 + arg2;
}
const add2 = (arg1: number, arg2: number): number => {
return arg1 + arg2;
};
console.log(add1(1,2));
console.log(add2(1,2));
2
3
4
5
6
7
8
使用接口和类型别名定义
interface Add {
(x: number, y: number): number;
}
let add: Add = (arg1: number, arg2: number): number => {
return arg1 + arg2
};
--------------------------------------------------------
type Add = (x: number, y: number) => number;
let add: Add = (arg1: number, arg2: number): number => {
return arg1 + arg2;
};
2
3
4
5
6
7
8
9
10
11
12
13
# 函数重载(9.1)
- 重写是指子类重写继承自父类的方法
- 重载是指为同一个函数提供多个类型定义
function add(arg1: number, arg2: number): number
function add(arg1: string, arg2: string): string
function add(arg1: any, arg2: any): any {
return arg1 + arg2
}
console.log(add(10, 20)); // 30
console.log(add("aaa", "bbb")); // aaabbb
2
3
4
5
6
7
8
9
# Class类(10)
类可以有自己的构造函数constructor,当我们通过new关键字创建 一个实例时,构造函数会被调用;
构造函数不需要返回任何值,默认返回当前创建出来的实例;
类中可以有自己的函数,定义的函数称之为方法;
# 类的成员修饰符(10.1)
类的属性和方法支持三种修饰符: public、private、protected
private
- 被声明的属性(方法)为私有的属性(方法),只能在类Animal
内部使用。protected
- 被声明的属性(方法)为受保护的属性(方法),即可以在类Animal
内部使用,也可以在子类中使用。public
- 被声明的属性(方法)为共有的属性(方法),不仅在类Animal
内部可以使用,也可以在子类和实例中使用。
# getters/setters(10.2)
私有属性我们是不能直接访问的,或者某些属性我们想要监听它的获取(getter)和设置(setter)的过程,这个时候我们 可以使用存取器。
class Person {
// 私有属性: 属性前面会使用_
private _name: string
private _age: number
constructor(name: string, age: number) {
this._name = name
this._age = age
}
running() {
console.log("running:", this._name)
}
// setter/getter: 对属性的访问进行拦截操作
set name(newValue: string) {
this._name = newValue
}
get name() {
return this._name
}
set age(newValue: number) {
if (newValue >= 0 && newValue < 200) {
this._age = newValue
}
}
get age() {
return this._age
}
}
const p = new Person("why", 100)
p.name = "kobe"
console.log(p.name)
p.age = -10
console.log(p.age)
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
# Readonly(10.3)
readonly
只能用于修饰属性,不能用于修饰方法。被 readonly
修饰的属性只能初始化阶段赋值和 constructor
中赋值。其他任何方式的赋值都是不被允许的。
class Cat {
private readonly name: string;
constructor(name: string) {
this.name = name;
}
changeName(name: string) {
this.name = name; // 报错:无法分配到“name”,因为它是常数或只读属性
}
sayHi(): string {
return `my name is ${this.name}`;
}
}
let tom = new Cat('Tom');
tom.changeName('Jack');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 静态属性和静态方法static
(10.4)
static 用于定义类的静态属性和方法。
静态属性和方法可直接通过类名访问,静态方法中只能访问静态属性和静态方法。
class Father {
public name: string
constructor(name: string) {
this.name = name
}
public static className: string = 'Father'
static getClassName(): string {
return Father.className
}
}
console.log(Father.className)
console.log(Father.getClassName())
2
3
4
5
6
7
8
9
10
11
12
13
# 抽象类(10.5)
被 abstract
修饰的类为抽象类,在抽象类中被 abstract
修饰的方法为抽象方法。抽象类不能被实例化,抽象类中的抽象方法必须被子类实现
父类本身可能并不需要对某些方法进行具体的实现,所以父类中定义的方法,,我们可以定义为抽象方法
抽象方法,必须存在于抽象类中; 抽象类是使用abstract声明的类;
抽象类是不能被实例的话(也就是不能通过new创建) 抽象方法必须被子类实现,否则该类必须是一个抽象类;
abstract class Animal {
public age = 10;
public abstract getAge(): number;
}
class Panda extends Animal {
public getAge() { return this.age; }
}
new Panda().getAge();
2
3
4
5
6
7
8
# 索引签名(11)
如果你不知道你要处理的对象结构,但你知道可能的键和值类型,那么索引签名就是你需要的。
索引签名由方括号中的索引名称及其类型组成,后面是冒号和值类型:{ [indexName: KeyType]: ValueType }
, KeyType
可以是一个 string
、number
或 symbol
,而ValueType
可以是任何类型。
一个索引签名的属性类型必须是 string 或者是 number。虽然 TS 可以同时支持 string 和 number 类型,但数字索引的返回类型一定要是字符索引返回类型的子类型;。
interface ICollection {
// 索引签名
[key: string]: number
length: number
}
function iteratorCollection(collection: ICollection) {
console.log(collection[0])
console.log(collection[1])
}
iteratorCollection({ name: 111, age: 18, length: 10 })
2
3
4
5
6
7
8
9
10
11
12
严格的字面量赋值
let arr = ["1", "2", "3"];
console.log(arr["forEach"] instanceof Function); // true
interface IIndexType1 {
[index: string]: string
}
interface IIndexType2 {
[index: number]: string
}
const names1: IIndexType1 = ["abc", "cba", "nba"] // 报错 可能会出现返回值不为string:见第一行代码
const names2: IIndexType2 = ["abc", "cba", "nba"]
2
3
4
5
6
7
8
9
10
11
12
# 泛型(12)
泛型简单来说就是类型变量,在 TS 中存在类型,如 number、string、boolean等。泛型就是使用一个类型变量来表示一种类型,类型值通常是在使用的时候才会设置
// function bar1(arg:string) {
// return arg;
// }
// const a = bar1(1);
// const b = bar1("a");
function bar<Type>(arg: Type): Type {
return arg
}
// 完整的写法
const res1 = bar<number>(123)
const res2 = bar<string>("abc")
const res3 = bar<{name: string}>({ name: "why" })
// 省略的写法
const res4 = bar("aaaaaaaaa")
const res5 = bar(11111111)
--------------------------------------------------
interface Per<Type = string> {
name: Type
age: number
slogan: Type
}
const Stu: Per<string> = {
name: "rio",
age: 20,
slogan: "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
# 泛型约束(13)
你可以声明一个类型参数,这个类型参数被其他类型参数约束
interface ILength {
length: number
}
function getInfo<Type extends ILength>(args: Type): Type {
return args
}
const info1 = getInfo("aaaa")
const info2 = getInfo(["aaa", "bbb", "ccc"])
const info3 = getInfo({ length: 100 })
------------------------------------------------------------
interface Per {
name: string
age: number
}
type Stu = keyof Per // "name" | "age"
function getObjectProperty<O, K extends keyof O>(obj: O, key: K){
return obj[key]
}
const info = {
name: "rio",
age: 20,
height: 1.75
}
const name1 = getObjectProperty(info, "name")
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
# 映射类型(14)
一个类型需要基于另外一个类型,但是不想拷贝一份,这个时候可以使用映射类型
映射修饰符
在使用映射类型时,有两个额外的修饰符可能会用到:
- 一个是
readonly
,用于设置属性只读; - 一个是 ? ,用于设置属性可选;
你可以通过前缀 - 或者 + 删除或者添加这些修饰符,如果没有写前缀,相当于使用了 + 前缀。
type MapPerson<Type> = {
// 索引类型以此进行使用 并转换成可选属性
[aaa in keyof Type]?: Type[aaa]
}
interface IPerson {
name: string
age: number
}
type NewPerson = MapPerson<IPerson>
----------------------------------------------------
type MapPerson<Type> = {
-readonly[aaa in keyof Type]-?: Type[aaa]
}
interface IPerson {
name: string
age: number
address: string
readonly height: number
}
type NewPerson = MapPerson<IPerson>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 泛型工具类型 (15)
# typeof (15.1)
typeof 的主要用途是在类型上下文中获取变量或者属性的类型
const Message = {
name: "jimmy",
age: 18,
address: {
province: '四川',
city: '成都'
}
}
type message = typeof Message;
/*
type message = {
name: string;
age: number;
address: {
province: string;
city: string;
};
}
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# keyof (15.2)
该操作符可以用于获取某种类型的所有键,其返回类型是联合类型。
interface Person {
name: string;
age: number;
}
type K1 = keyof Person; // "name" | "age"
2
3
4
5
6
实战中用处
function prop(obj, key) {
return obj[key];
}
// 该函数接收 obj 和 key 两个参数,并返回对应属性的值。对象上的不同属性,可以具有完全不同的类型
// 简单处理
function prop(obj: object, key: string) {
return obj[key]; #报错 元素隐式地拥有 any 类型,因为 string 类型不能被用于索引 {} 类型
}
// 改进
function prop<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
-------------------------------
type Todo = {
id: number;
text: string;
done: boolean;
}
const todo: Todo = {
id: 1,
text: "Learn TypeScript keyof",
done: false
}
function prop<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const id = prop(todo, "id"); // const id: number
const text = prop(todo, "text"); // const text: string
const done = prop(todo, "done"); // const done: boolean
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
# in (15.3)
用来遍历枚举类型
type Keys = "a" | "b" | "c"
type Obj = {
[p in Keys]: any
} // -> { a: any, b: any, c: any }
2
3
4
5
# Partial (15.4)
将类型的属性变成可选
interface UserInfo {
id: string;
name: string;
}
type NewUserInfo = Partial<UserInfo>;
const xiaoming: NewUserInfo = {
name: 'xiaoming'
}
2
3
4
5
6
7
8
Partial<T>
有个局限性,就是只支持处理第一层的属性
interface UserInfo {
id: string;
name: string;
fruits: {
appleNumber: number;
orangeNumber: number;
}
}
type DeepPartial<T> = {
[U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U]
};
const xiaoming: DeepPartial<UserInfo> = {
name: 'xiaoming',
fruits: {
orangeNumber: 1,
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Required (15.5)
Required将类型的属性变成必选
interface UserInfo {
id: string;
name: string;
}
type MyRequired<T> = {
[K in keyof T]-?: T[K]
}
type Person = MyRequired<UserInfo>
const xiaoming: Person = {
id: '007',
name: 'xiaoming',
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Pick (15.6)
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,
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Record (15.7)
Record<K extends keyof any, T>
的作用是将 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" },
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ReturnType (15.8)
用来得到一个函数的返回值类型
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R: any;
type Func = (value: number) => string;
const foo: ReturnType<Func> = "1";
// ReturnType获取到 Func 的返回值类型为 string,所以,foo 也就只能被赋值为字符串了。
2
3
4
5
# Exclude (15.9)
Exclude<T, U>
的作用是将某个类型中属于另一个的类型移除掉
type Exclude<T, U> = T extends U ? never : T;
// 如果 T 能赋值给 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
2
3
4
5
6
# Extract (15.10)
Extract<T, U>
的作用是从 T
中提取出 U
。
type Extract<T, U> = T extends U ? T : never;
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () =>void
2
3
4
# Omit (15.11)
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 TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
2
3
4
5
6
7
8
9
10
11
12
13
14
# NonNullable (15.12)
NonNullable<T>
的作用是用来过滤类型中的 null
及 undefined
类型。
type NonNullable<T> = T extends null | undefined ? never : T;
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
2
3
4
# Parameters (15.13)
Parameters<T>
的作用是用于获得函数的参数类型组成的元组类型。
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
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[]
2
3
4
5
6
# InstanceType (15.14)
用于构造一个由所有Type的构造函数的实例类型组成的类型。
# TS模块化 (16)
- JavaScript 规范声明任何没有 export 的 JavaScript 文件都应该被认为是一个脚本,而非一个模块。
- 在一个脚本文件中,变量和类型会被声明在共享的全局作用域,将多个输入文件合并成一个输出文件,或者在 HTML使用多 个
// type.ts
interface IPerson {
name: string
age: number
}
type IDType = number | string
export {
IPerson,
IDType
}
// index.ts
// 添加type关键字可以让非 TypeScript 编译器比如 Babel、swc 或者 esbuild 知道什么样的导入可以被安全移除。
import type { IDType, IPerson } from "./utils/type"
const id1: IDType = 111
const p: IPerson = { name: "why", age: 18 }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 命名空间 (16.1)
已经不常用
// format.ts
export namespace price {
export function format(price: string) {
return "¥" + price
}
export const name = "price"
}
export namespace date {
export function format(dateString) {
return "2023-3-9"
}
const name = "date"
}
// index.ts
import { price, date } from "./utils/format";
// 使用命名空间中的内容
price.format("1111")
date.format("22222")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 类型的声明 (17)
.d.ts
文件,它是用来做类型的声明(declare),称之为类型声明(Type Declaration)或者类型定义(Type Definition)文件
- 内置类型声明;
内置类型声明是Typescript自带的、帮助我们内置了JavaScript运行时的一些标准化API的声明文件; 包括比如Function、String、Math、Date等内置类型;也包括运行环境中的DOM API,比如Window、Document等;
lib.[something].d.ts
- 外部定义类型声明;
使用第三方库时,需要的一些类型声明,该库查找声明安装方式的地址:https://www.typescriptlang.org/dt/search?search=
- 自定义类型声明;
我们给自己的代码中声明一些类型,方便在其他地方直接进行使用;
// 声明文件模块
declare module "*.png"
// 为自己的 变量/函数/类 定义类型声明
declare const myName: string
2
3
4
# tsconfig.json (1)
tsconfig.json 是 TypeScript 项目的配置文件。如果一个目录下存在一个 tsconfig.json 文件,那么往往意味着这个目录就是 TypeScript 项目的根目录。
tsconfig.json 包含 TypeScript 编译的相关配置,通过更改编译配置项,我们可以让 TypeScript 编译出 ES6、ES5、node 的代码
- files - 编写一个数组设置要编译的文件的名称;
- include - 编写一个数组设置需要进行编译的文件,支持路径模式匹配;
- exclude - 编写一个数组设置无需进行编译的文件,支持路径模式匹配;
- compilerOptions - 设置与编译流程相关的选项
{ "compilerOptions": {
/* 基本选项 */ "target": "es5", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "module": "commonjs", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015' "lib": [], // 指定要包含在编译中的库文件 "allowJs": true, // 允许编译 javascript 文件 "checkJs": true, // 报告 javascript 文件中的错误 "jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react' "declaration": true, // 生成相应的 '.d.ts' 文件 "sourceMap": true, // 生成相应的 '.map' 文件 "outFile": "./", // 将输出文件合并为一个文件 "outDir": "./", // 指定输出目录 "rootDir": "./", // 用来控制输出目录结构 --outDir. "removeComments": true, // 删除编译后的所有的注释 "noEmit": true, // 不生成输出文件 "importHelpers": true, // 从 tslib 导入辅助工具函数 "isolatedModules": true, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似). /* 严格的类型检查选项 */ "strict": true, // 启用所有严格类型检查选项 "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错 "strictNullChecks": true, // 启用严格的 null 检查 "noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误 "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict' /* 额外的检查 */ "noUnusedLocals": true, // 有未使用的变量时,抛出错误 "noUnusedParameters": true, // 有未使用的参数时,抛出错误 "noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误 "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿) /* 模块解析选项 */ "moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) "baseUrl": ".", // 用于解析非相对模块名称的基目录 "paths": {"@/*":["src/*"]}, // 模块名到基于 baseUrl 的路径映射的列表 "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容 "typeRoots": [], // 包含类型声明的文件列表 "types": [], // 需要包含的类型声明文件名列表 "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。 /* Source Map Options */ "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置 "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置 "inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件 "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性 /* 其他选项 */ "experimentalDecorators": true, // 启用装饰器 "emitDecoratorMetadata": true // 为装饰器提供元数据的支持
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} }
# 参考
2022 typescript史上最强学习入门文章(2w字) - 掘金 (juejin.cn) (opens new window)
Issues · semlinker/awesome-typescript (github.com) (opens new window)