1.安装
npm install typescript@next
2.vscode通过创建.vscode/settings.json来使用这个版本;
- {
- "typescript.tsdk":"./node_modules/typescript/lib"
- }
1. TypeScript 有两个“顶层类型”(any
和unknown
),但是“底层类型”只有never
唯一一个
unknown
类型变量能够进行的运算是有限的,只能进行比较运算(运算符==
、===
、!=
、!==
、||
、&&
、?
)、取反运算(运算符!
)、typeof
运算符和instanceof
运算符这几种,其他运算都会报错。可以先把类型确认了再赋值给其他;
- let a:unknown = 1;
-
- if (typeof a === 'number') {
- let r = a + 10; // 正确
- }
2. ts基本类型
- boolean
true
和false
两个布尔值- string 普通字符串和模板字符串
- number 整数、浮点数和非十进制数
- bigint 大整数带n,如果赋值为整数和小数,都会报错
- symbol Symbol 值
- object 所有对象、数组和函数
- undefined 值
undefined
,表示未定义(即还未给出定义,以后可能会有定义)- null 值
null
,表示为空(即此处没有值)
上面所有类型的名称都是小写字母,首字母大写的Number
、String
、Boolean
等在 JavaScript 语言中都是内置对象,而不是类型名称,String()
只有当作构造函数使用时(即带有new
命令调用),才会返回包装对象。如果当作普通函数使用(不带有new
命令),返回就是一个普通字符串。其他两个构造函数Number()
和Boolean()
也是如此,大写类型同时包含包装对象和字面量两种情况,小写类型只包含字面量,不包含包装对象,建议只使用小写类型,不使用大写类型,TypeScript 把很多内置方法的参数,定义成小写类型,使用大写类型会报错。undefined 和 null 既可以作为值,也可以作为类型;bigint 类型是 ES2020 标准引入的。如果使用这个类型,TypeScript 编译的目标 JavaScript 版本不能低于 ES2020(即编译参数target
不低于es2020;
除了undefined
和null
这两个值不能转为对象,其他任何值都可以赋值给Object
类型,变量obj
的类型是空对象{}
,就代表Object
类型。显然,无所不包的Object
类型既不符合直觉,也不方便使用,object
类型不包含原始类型值,只包含对象、数组和函数;
3. JavaScript 语言中,typeof 运算符是一个一元运算符,返回一个字符串,代表操作数的类型。typeof 是一个很重要的 TypeScript 运算符,有些场合不知道某个变量foo
的类型,这时使用typeof foo
就可以获得它的类型;
4. 元组(tuple)是 TypeScript 特有的数据类型,JavaScript 没有单独区分这种类型。它表示成员类型可以自由设置的数组,即数组的各个成员的类型可以不同,扩展运算符(...
)将数组(注意,不是元组)转换成一个逗号分隔的序列;
5. Symbol 是 ES2015 新引入的一种原始类型的值。它类似于字符串,但是每一个 Symbol 值都是独一无二的,与其他任何值都不相等。Symbol 值通过Symbol()
函数生成。在 TypeScript 里面,Symbol 的类型使用symbol
表示。
6. 函数的类型声明,需要在声明函数时,给出参数的类型和返回值的类型。函数类型还可以采用对象的写法(可以使用 Interface 来声明),(这种写法平时很少用,但是非常合适用在一个场合:函数本身存在属性);TypeScript 提供 Function 类型表示函数,任何函数都属于这个类型。如果函数的某个参数可以省略,则在参数名后面加问号表示。参数名带有问号?,表示该参数的类型实际上是原始类型|undefined
,它有可能为undefined,
参数x
后面有问号,表示该参数可以省略, 函数的可选参数只能在参数列表的尾部,跟在必选参数的后面;rest 参数表示函数剩余的所有参数,它可以是数组(剩余参数类型相同),也可能是元组(剩余参数类型不同);如果函数内部不能修改某个参数,可以在函数定义时,在参数类型前面加上readonly
关键字,表示这是只读参数;void 类型表示函数没有返回值,void 类型允许返回undefined
或null,never
类型不同于void
类型。前者表示函数没有执行结束,不可能有返回值;后者表示函数正常执行结束,但是不返回值,或者说返回undefined;
函数内部允许声明其他类型,该类型只在函数内部有效,称为局部类型,一个函数的返回值还是一个函数,那么前一个函数就称为高阶函数(higher-order function);构造函数的最大特点,就是必须使用new
命令调用;
7.
对象赋值时,就不能缺少指定的属性,也不能有多余的属性,也不能删除类型声明中存在的属性,修改属性值是可以的,也不能删除类型声明中存在的属性,修改属性值是可以的,对象类型可以使用方括号读取属性的类型,除了type
命令可以为对象类型声明一个别名,TypeScript 还提供了interface
命令,可以把对象类型提炼为一个接口,注意,TypeScript 不区分对象自身的属性和继承的属性,一律视为对象的属性,如果某个属性是可选的(即可以忽略),需要在属性名后面加一个问号,可选属性等同于允许赋值为undefined,若
是可选属性,需要判断是否为undefined
以后,才能使用,用三元运算符?: 或者 Null 判断运算符 ??(??后面是否定的情况的值),
属性名前面加上readonly
关键字,表示这个属性是只读属性,不能修改,如果希望属性值是只读的,除了声明时加上readonly
关键字,还有一种方法,就是在赋值时,在对象后面加上只读断言as const,
所有的数值属性名都会自动转为字符串属性名;
- // 写法一
- let firstName = (user.firstName === undefined)
- ? 'Foo' : user.firstName;
- let lastName = (user.lastName === undefined)
- ? 'Bar' : user.lastName;
-
- // 写法二
- let firstName = user.firstName ?? 'Foo';
- let lastName = user.lastName ?? 'Bar';
8. interface 是对象的模板,可以看作是一种类型约定,中文译为“接口”。使用了某个模板的对象,就拥有了指定的类型结构,interface 可以使用extends
关键字,继承其他 interface(父接口),多重接口继承,实际上相当于多个父接口的合并,如果子接口与父接口存在同名属性,那么子接口的属性会覆盖父接口的属性。注意,子接口与父接口的同名属性必须是类型兼容的,不能有冲突,否则会报错,interface 可以继承type
命令定义的对象类型, 如果type
命令定义的类型不是对象,interface 就无法继承,interface 还可以继承 class,即继承该类的所有成员,clone()
方法有不同的类型声明,会发生函数重载。这时,越靠后的定义,优先级越高,排在函数重载的越前面,类型声明的参数x
是字面量类型,这个类型声明的优先级最高,会排在函数重载的最前面(1)type
能够表示非对象类型,而interface
只能表示对象类型(包括数组、函数等),(2)interface
可以继承其他类型,type
不支持继承, &
运算符,表示同时具备两个类型的特征,因此可以起到两个对象类型合并的作用,同名interface
会自动合并,同名type
则会报错,TypeScript 不允许使用type
多次定义同一个类型, interface 是开放的,可以添加属性,type 是封闭的,不能添加属性,只能定义新type;interface 是开放的,可以添加属性,type 是封闭的,不能添加属性,只能定义新的 type;this
关键字只能用于interface;
type 可以扩展原始数据类型,interface 不行;interface
无法表达某些复杂类型(比如交叉类型和联合类型),但是type
可以;综上所述,如果有复杂的类型运算,那么没有其他选择只能使用type
;一般情况下,interface
灵活性比较高,便于扩充类型或自动合并,建议优先使用。
9. 类(class)是面向对象编程的基本构件,封装了属性和方法;属性名后面添加了感叹号!,表示这两个属性肯定不会为空;;类的方法就是普通函数,类型声明方式与函数一致;构造方法constructor()
和普通方法add()
都注明了参数类型,但是省略了返回值类型,因为 TypeScript 可以自己推断出来,构造方法不能声明返回值类型,否则报错,因为它总是返回实例对象;
存取器(accessor)是特殊的类方法,包括取值器(getter)和存值器(setter)两种方法。它们用于读写某个属性,取值器用来读取属性,存值器用来写入属性;如果某个属性只有get
方法,没有set
方法,那么该属性自动成为只读属性。get
方法与set
方法的可访问性必须一致,要么都为公开方法,要么都为私有方法。
interface 接口或 type 别名,可以用对象的形式,为 class 指定一组检查条件。然后,类使用 implements 关键字,表示当前类满足这些外部类型条件的限制。
- interface MotorVehicle {
- // ...
- }
- interface Flyable {
- // ...
- }
- interface Swimmable {
- // ...
- }
-
- interface SuperCar extends MotoVehicle,Flyable, Swimmable {
- // ...
- }
-
- class SecretCar implements SuperCar {
- // ...
- }
要获得一个类的自身类型,一个简便的方法就是使用 typeof 运算符
- interface PointConstructor {
- new(x:number, y:number):Point;
- }
-
- function createPoint(
- PointClass: PointConstructor,
- x: number,
- y: number
- ):Point {
- return new PointClass(x, y);
- }
函数fn()
的参数是一个空类,这意味着任何对象都可以用作fn()
的参数。确定两个类的兼容关系时,只检查实例成员,不考虑静态成员和构造方法;如果类中存在私有成员(private)或保护成员(protected),那么确定兼容关系时,TypeScript 要求私有成员和保护成员来自同一个类,这意味着两个类需要存在继承关系;
类(这里又称“子类”)可以使用 extends 关键字继承另一个类(这里又称“基类”)的所有属性和方法。如果基类包括保护成员(protected
修饰符),子类可以将该成员的可访问性设置为公开(public
修饰符),也可以保持保护成员不变,但是不能改用私有成员(private
修饰符)
extends
关键字后面不一定是类名,可以是一个表达式,只要它的类型是构造函数就可以了;
类的内部成员的外部可访问性,由三个可访问性修饰符(access modifiers)控制:public
、private
和protected
。
public
修饰符表示这是公开成员,外部可以自由访问。public
修饰符是默认修饰符,如果省略不写,实际上就带有该修饰符。因此,类的属性和方法默认都是外部可访问的。
private
修饰符表示私有成员,只能用在当前类的内部,类的实例和子类都不能使用该成员。TypeScript 对于访问private
成员没有严格禁止,使用方括号写法([]
)或者in
运算符,实例对象就能访问该成员;ES2022 引入了自己的私有成员写法#propName
。因此建议不使用private
,改用 ES2022 的写法,获得真正意义的私有成员。私有成员写法(属性名前加#
)
protected
修饰符表示该成员是保护成员,只能在类的内部使用该成员,实例无法使用该成员,但是子类内部可以使用。
类的内部可以使用static
关键字,定义静态成员,静态成员是只能通过类本身使用的成员,不能通过实例对象使用,static
关键字前面可以使用 public、private、protected 修饰符。
类也可以写成泛型,使用类型参数,静态成员不能使用泛型的类型参数;
- class Box<Type> {
- contents: Type;
-
- constructor(value:Type) {
- this.contents = value;
- }
- }
-
- const b:Box<string> = new Box('hello!');
TypeScript 允许在类的定义前面,加上关键字abstract
,表示该类不能被实例化,只能当作其他类的模板。这种类就叫做“抽象类”(abstract class),抽象类的子类也可以是抽象类,也就是说,抽象类可以继承其他抽象类。抽象类的内部可以有已经实现好的属性和方法,也可以有还未实现的属性和方法。后者就叫做“抽象成员”(abstract member),即属性名和方法名有abstract
关键字,表示该方法需要子类实现。如果子类没有实现抽象成员,就会报错。)抽象成员只能存在于抽象类,不能存在于普通类。)抽象成员不能有具体实现的代码。也就是说,已经实现好的成员前面不能加abstract
关键字。)抽象成员前也不能有private
修饰符,否则无法在子类中实现该成员。)一个子类最多只能继承一个抽象类。
类的方法经常用到this
关键字,它表示该方法当前所在的对象。在类的内部,this
本身也可以当作类型使用,表示当前类的实例对象。有些方法返回一个布尔值,表示当前的this
是否属于某种类型。这时,这些方法的返回值类型可以写成this is Type
的形式,其中用到了is
运算符。
10. 有些时候,函数返回值的类型与参数类型是相关的。TypeScript 就引入了“泛型”(generics)。泛型的特点就是带有“类型参数”(type parameter)。示例中,函数getFirst()
的函数名后面尖括号的部分
,就是类型参数,参数要放在一对尖括号(<>
)里面。本例只有一个类型参数T
,可以将其理解为类型声明需要的变量,需要在调用时传入具体的参数类型。函数getFirst()
的参数类型是T[]
,返回值类型是T
,就清楚地表示了两者之间的关系。比如,输入的参数类型是number[]
,那么 T 的值就是number
,因此返回值类型也是number
。
- function getFirst<T>(arr:T[]):T {
- return arr[0];
- }
泛型主要用在四个场合:函数、接口、类和别名。
11.实际开发中,经常需要定义一组相关的常量,TypeScript 就设计了 Enum 结构,用来将相关常量放在一个容器里面,方便使用。Enum 结构的特别之处在于,它既是一种类型,也是一个值。绝大多数 TypeScript 语法都是类型语法,编译后会全部去除,但是 Enum 结构是一个值,编译后会变成 JavaScript 对象,留在代码中。TypeScript 的定位是 JavaScript 语言的类型增强,所以官方建议谨慎使用 Enum 结构,因为它不仅仅是类型,还会为编译后的代码加入一个对象。Enum 结构比较适合的场景是,成员的值不重要,名字更重要,从而增加代码的可读性和可维护性。由于 Enum 结构编译后是一个对象,所以不能有与它同名的变量(包括对象、函数、类等)Enum 每个成员的值都是显式赋值。成员的值可以是任意数值,但不能是大整数(Bigint)。
keyof 运算符可以取出 Enum 结构的所有成员名,作为联合类型返回,搭配typeof使用。要返回 Enum 所有的成员值,可以使用in
运算符。
12. TypeScript 提供了“类型断言”这样一种手段,允许开发者在代码中“断言”某个值的类型,告诉编译器此处的值是什么类型。TypeScript 一旦发现存在类型断言,就不再对该值进行类型推断,而是直接采用断言给出的类型。
- // 语法一:<类型>值
- <Type>value
-
- // 语法二:值 as 类型
- value as
-
- eg:
-
- // 语法一
- let bar:T = <T>foo;
-
- // 语法二
- let bar:T = foo as T;
类型断言不应滥用,因为它改变了 TypeScript 的类型检查,很可能埋下错误的隐患。
- const data:object = {
- a: 1,
- b: 2,
- c: 3
- };
-
- data.length; // 报错
-
- (data as Array<string>).length; // 正确
变量data
是一个对象,没有length
属性。但是通过类型断言,可以将它的类型断言为数组,这样使用length
属性就能通过类型检查。但是,编译后的代码在运行时依然会报错,所以类型断言可以让错误的代码通过编译。
类型断言的一大用处是,指定 unknown 类型的变量的具体类型。
- const value:unknown = 'Hello World';
-
- const s1:string = value; // 报错
- const s2:string = value as string; // 正确
上面示例中,unknown 类型的变量value
不能直接赋值给其他类型的变量,但是可以将它断言为其他类型,这样就可以赋值给别的变量了。
另外,类型断言也适合指定联合类型的值的具体类型。
类型断言的使用前提是,值的实际类型与断言的类型必须满足一个条件。expr
是实际的值,T
是类型断言,它们必须满足下面的条件:expr
是T
的子类型,或者T
是expr
的子类型。
- expr as T
-
- 通过两次类型断言,变量n的类型就从数值,变成了完全无关的字符串,从而赋值时不会报错。
-
- expr as unknown as T
TypeScript 提供了一种特殊的类型断言as const
,用于告诉编译器,推断类型时,可以将这个值推断为常量,即把 let 变量断言为 const 变量,从而把内置的基本类型变更为值类型。使用了as const
断言以后,let 变量就不能再改变值了。as const断言只能用于字面量,不能用于变量;as const
也不能用于表达式;as const
断言可以用于整个对象,也可以用于对象的单个属性,这时它的类型缩小效果是不一样的。
- // 后置形式
- expr as const
-
- // 前置形式
- <const>expr
对于那些可能为空的变量(即可能等于undefined
或null
),TypeScript 提供了非空断言,保证这些变量不会为空,写法是在变量名后面加上感叹号!
。非空断言在实际编程中很有用,有时可以省去一些额外的判断。非空断言只有在打开编译选项strictNullChecks
时才有意义。如果不打开这个选项,编译器就不会检查某个变量是否可能为undefined
或null
。
断言函数的asserts
语句等同于void
类型,所以如果返回除了undefined
和null
以外的值,都会报错
13. 任何包含 import 或 export 语句的文件,就是一个模块(module)。相应地,如果文件不包含 export 语句,就是一个全局的脚本文件。
模块本身就是一个作用域,不属于全局作用域。模块内部的变量、函数、类只在内部可见,对于模块外部是不可见的。暴露给外部的接口,必须用 export 命令声明;如果其他文件要使用模块的接口,必须用 import 命令来输入;
import 在一条语句中,可以同时输入类型和正常接口。第一个方法是在 import 语句输入的类型前面加上type
关键字。第二个方法是使用 import type 语句,这个语句只能输入类型,不能输入正常接口。export同理
- type A = 'a';
- type B = 'b';
-
- // 方法一
- export {type A, type B};
-
- // 方法二
- export type {A, B};
CommonJS 是 Node.js 的专用模块格式,与 ES 模块格式不兼容。除了使用import =
语句,TypeScript 还允许使用import * as [接口名] from "模块文件"
输入 CommonJS 模块。TypeScript 使用export =
语句,输出 CommonJS 模块的对象,等同于 CommonJS 的module.exports
对象。export =
语句输出的对象,只能使用import =
语句加载。
路径映射:baseUrl
字段可以手动指定脚本模块的基准目录。paths
字段指定非相对路径的模块与实际脚本的映射。rootDirs
字段指定模块定位时必须查找的其他目录。
14. 装饰器(Decorator)是一种语法结构,用来在定义时修改类(class)的行为。)第一个字符(或者说前缀)是@
,后面是一个表达式。)@
后面的表达式,必须是一个函数(或者执行后可以得到一个函数))这个函数接受所修饰对象的一些相关值作为参数。)这个函数要么不返回值,要么返回一个新对象取代所修饰的目标对象;执行顺序:原型方法的装饰器首先应用,然后是静态属性和静态方法装饰器,接下来是实例属性装饰器,最后是类装饰器,如果一个方法或属性有多个装饰器,则内层的装饰器先执行,外层的装饰器后执行。
- type Decorator = ( //装饰器的类型定义。它是一个函数,使用时会接收到value和context两个参数
- value: DecoratedValue, //所装饰的对象。
- context: { //上下文对象,TypeScript 提供一个原生接口,对象的属性,根据所装饰对象的不同而不同,其中只有两个属性(kind和name)是必有的,其他都是可选的。
- kind: string; //字符串,表示所装饰对象的类型,可能取以下的值'class','method','getter','setter','field','accessor'六种装饰器
- name: string | symbol; //字符串或者 Symbol 值,所装饰对象的名字,比如类名、属性名等
- addInitializer?(initializer: () => void): void; //函数,用来添加类的初始化逻辑,没有返回值
- static?: boolean; //布尔值,表示所装饰的对象是否为类的静态成员。
- private?: boolean; //布尔值,表示所装饰的对象是否为类的私有成员。
- access: { //一个对象,包含了某个值的 get 和 set 方法。
- get?(): unknown;
- set?(value: unknown): void;
- };
- }
- ) => void | ReplacementValue;
-
-
- 装饰器种类:
- 类装饰器(Class Decorators):用于类。
- 属性装饰器(Property Decorators):用于属性。
- 方法装饰器(Method Decorators):用于方法。
- 存取器装饰器(Accessor Decorators):用于类的 set 或 get 方法。
- 参数装饰器(Parameter Decorators):用于方法的参数。
-
-
- 装饰器执行顺序:实例相关的装饰器——>静态相关的装饰器——>构造方法的参数装饰器——>类装饰器
15. declare 关键字用来告诉编译器,某个类型是存在的,可以在当前文件中使用。可以描述一下类型:变量(const、let、var 命令声明),type 或者 interface 命令声明的类型,class,enum,函数(function),模块(module),命名空间(namespace);declare 关键字只用来给出类型描述,是纯的类型代码,不允许设置变量的初始值,即不能涉及值;
16. 类型声明文件里面只有类型代码,没有具体的代码实现。它的文件名一般为[模块名].d.ts
的形式,其中的d
表示 declaration(声明)。
三斜杠命令(///
)是一个 TypeScript 编译器命令,用来指定编译器行为。它只能用在文件的头部,如果用在其他地方,会被当作普通的注释。另外,若一个文件中使用了三斜线命令,那么在三斜线命令之前只允许使用单行注释、多行注释和其他三斜线命令,否则三斜杠命令也会被当作普通的注释。///
17. keyof 是一个单目运算符,接受一个对象类型作为参数,返回该对象的所有键名组成的联合类型。 keyof 返回的类型是string|number|symbol;-?
表示去除可选属性设置。对应地,还有+?
的写法,表示添加可选属性设置;
JavaScript 语言中,in
运算符用来确定对象是否包含某个属性名。in
运算符的左侧是一个字符串,表示属性名,右侧是一个对象。它的返回值是一个布尔值。TypeScript 语言的类型运算中,in
运算符有不同的用法,用来取出(遍历)联合类型的每一个成员类型。
方括号运算符([]
)用于取出对象的键值类型,比如T[K]
会返回对象T
的属性K
的类型。
条件运算符extends...?:
可以根据当前类型是否符合某种条件,返回不同的类型。
infer
关键字用来定义泛型里面推断出来的类型参数,而不是外部传入的类型参数。
is
运算符用来描述返回值属于true
还是false
。is
运算符总是用于描述函数的返回值类型,写法采用parameterName is Type
的形式,即左侧为当前函数的参数名,右侧为某一种类型。它返回一个布尔值,表示左侧参数是否属于右侧的类型。
模板字符串`${ } `可以引用的类型一共6种,分别是 string、number、bigint、boolean、null、undefined。引用这6种以外的类型会报错。
satisfies
运算符用来检测某个值是否符合指定类型
18. 映射(mapping)指的是,将一种类型按照映射规则,转换成另一种类型,通常用于对象类型。映射会原样复制原始对象的可选属性和只读属性+
修饰符:写成+?
或+readonly
,为映射属性添加?
修饰符或readonly
修饰符。–
修饰符:写成-?
或-readonly
,为映射属性移除?
修饰符或readonly
修饰符。
19. TypeScript 提供了一些内置的类型工具,用来方便地处理各种类型,以及生成新的类型。
- Awaited<Type> //用来取出 Promise 的返回值类型,适合用在描述then()方法和 await 命令的参数类型。
- ConstructorParameters<Type> //ConstructorParameters<Type>提取构造方法Type的参数类型,组成一个元组类型返回。
- Exclude<UnionType, ExcludedMembers> //Exclude<UnionType, ExcludedMembers>用来从联合类型UnionType里面,删除某些类型ExcludedMembers,组成一个新的类型返回。
- Extract<Type, Union> //用来从联合类型UnionType之中,提取指定类型Union,组成一个新类型返回。它与Exclude<T, U>正好相反
- InstanceType<Type> //提取构造函数的返回值的类型(即实例类型),参数Type是一个构造函数,等同于构造函数的ReturnType<Type>
- NonNullable<Type> //用来从联合类型Type删除null类型和undefined类型,组成一个新类型返回,也就是返回Type的非空类型版本
- Omit<Type, Keys> //用来从对象类型Type中,删除指定的属性Keys,组成一个新的对象类型返回
- OmitThisParameter<Type> //从函数类型中移除 this 参数。
- Parameters<Type> //从函数类型Type里面提取参数类型,组成一个元组返回。
- Partial<Type> //返回一个新类型,将参数类型Type的所有属性变为可选属性。
- Pick<Type, Keys> //返回一个新的对象类型,第一个参数Type是一个对象类型,第二个参数Keys是Type里面被选定的键名。
- Readonly<Type> //返回一个新类型,将参数类型Type的所有属性变为只读属性。
- Record<Keys, Type> //返回一个对象类型,参数Keys用作键名,参数Type用作键值类型。
- Required<Type> //返回一个新类型,将参数类型Type的所有属性变为必选属性。它与Partial<Type>的作用正好相反。
- ReadonlyArray<Type> //用来生成一个只读数组类型,类型参数Type表示数组成员的类型。
- ReturnType<Type> //提取函数类型Type的返回值类型,作为一个新类型返回。
- ThisParameterType<Type> //提取函数类型中this参数的类型。
- ThisType<Type> //不返回类型,只用来跟其他类型组成交叉类型,用来提示 TypeScript 其他类型里面的this的类型。
TypeScript 内置了四个字符串类型工具,专门用来操作字符串类型。这四个工具类型都定义在 TypeScript 自带的.d.ts
文件里面。
- Uppercase<StringType>将字符串类型的每个字符转为大写。
- Lowercase<StringType>将字符串的每个字符转为小写。
- Capitalize<StringType>将字符串的第一个字符转为大写。
- Uncapitalize<StringType> 将字符串的第一个字符转为小写。
20.tsconfig.json
是 TypeScript 项目的配置文件,放在项目的根目录。反过来说,如果一个目录里面有tsconfig.json
,TypeScript 就认为这是项目的根目录
- include //指定哪些文件需要编译,指定所要编译的文件列表,既支持逐一列出文件,也支持通配符(?:指代单个字符;*:指代任意字符,不含路径分隔符;**:指定任意目录层级。),文件位置相对于当前配置文件而定,如果不指定文件后缀名,默认包括.ts、.tsx和.d.ts文件。如果打开了allowJs,那么还包括.js和.jsx;
- allowJs //指定源目录的 JavaScript 文件是否原样拷贝到编译后的目录, 允许 TypeScript 项目加载 JS 脚本。编译时,也会将 JS 文件,一起拷贝到输出目录。
- exclude //是一个数组,必须与include属性一起使用,用来从编译列表中去除指定的文件。它也支持使用与include属性相同的通配符。
- extends //用来指定所要继承的配置文件。它可以是本地文件。extends指定的tsconfig.json会先加载,然后加载当前的tsconfig.json。如果两者有重名的属性,后者会覆盖前者
- files //指定编译的文件列表,如果其中有一个文件不存在,就会报错。
- references //是一个数组,数组成员为对象,适合一个大项目由许多小项目构成的情况,用来设置需要引用的底层项目。
- compileOptions //用来定制编译行为。这个属性可以省略,这时编译器将使用默认设置。
- alwaysStrict //确保脚本以 ECMAScript 严格模式进行解析,因此脚本头部不用写"use strict"。它的值是一个布尔值,默认为true
- allowSyntheticDefaultImports //允许import命令默认加载没有default输出的模块。
- allowUnreachableCode //设置是否允许存在不可能执行到的代码。值有三种可能: undefined: 默认值,编辑器显示警告;true:忽略不可能执行到的代码;false:编译器报错。
- allowUnusedLabels //设置是否允许存在没有用到的代码标签(label)。值有三种可能: undefined: 默认值,编辑器显示警告;true:忽略没有用到的代码标签;false:编译器报错
- baseUrl //值为字符串,指定 TypeScript 项目的基准目录,由于默认是以 tsconfig.json 的位置作为基准目录,所以一般情况不需要使用该属性
- checkJs //设置对 JS 文件同样进行类型检查。它等同于在 JS 脚本的头部添加// @ts-check命令,这个属性,也会自动打开allowJs。
- composite //打开某些设置,使得 TypeScript 项目可以进行增量构建,往往跟incremental属性配合使用。
- declaration //设置编译时是否为每个脚本生成类型声明文件.d.ts。
- declarationDir //设置生成的.d.ts文件所在的目录。
- declarationMap //设置生成.d.ts类型声明文件的同时,还会生成对应的 Source Map 文件。
- emitBOM //设置是否在编译结果的文件头添加字节顺序标志 BOM,默认值是false。
- emitDeclarationOnly //设置编译后只生成.d.ts文件,不生成.js文件。
- esModuleInterop //修复了一些 CommonJS 和 ES6 模块之间的兼容性问题。
- exactOptionalPropertyTypes //设置可选属性不能赋值为undefined
- forceConsistentCasingInFileNames //设置文件名是否为大小写敏感,默认为true
- incremental //让 TypeScript 项目构建时产生文件tsbuildinfo,从而完成增量构建。
- inlineSourceMap //设置将 SourceMap 文件写入编译后的 JS 文件中,否则会单独生成一个.js.map文件。
- inlineSources //设置将原始的.ts代码嵌入编译后的 JS 中。它要求sourceMap或inlineSourceMap至少打开一个。
- isolatedModules //设置如果当前 TypeScript 脚本作为单个模块编译,是否会因为缺少其他脚本的类型信息而报错,主要便于非官方的编译工具(比如 Babel)正确编译单个脚本。
- jsx //设置如何处理.tsx文件。它可以取以下五个值: 1.preserve:保持 jsx 语法不变,输出的文件名为.jsx。2.react:将<div />编译成React.createElement("div"),输出的文件名为.js。3.react-native:保持 jsx 语法不变,输出的文件后缀名为.js。4.react-jsx:将<div />编译成_jsx("div"),输出的文件名为.js。5.react-jsxdev:跟react-jsx类似,但是为_jsx()加上更多的开发调试项,输出的文件名为.js。
- lib //值是一个数组,描述项目需要加载的 TypeScript 内置类型描述文件,跟三斜线指令/// <reference lib="" />作用相同。
- listEmittedFiles //设置编译时在终端显示,生成了哪些文件。
- listFiles //设置编译时在终端显示,参与本次编译的文件列表。
- mapRoot //指定 SourceMap 文件的位置,而不是默认的生成位置。
- module //指定编译产物的模块格式。它的默认值与target属性有关,如果target是ES3或ES5,它的默认值是commonjs,否则就是ES6/ES2015。它可以取以下值:none、commonjs、amd、umd、system、es6/es2015、es2020、es2022、esnext、node16、nodenext。
- moduleResolution //确定模块路径的算法,即如何查找模块。它的默认值与module属性有关,如果module为AMD、UMD、System或ES6/ES2015,默认值为classic;如果module为node16或nodenext,默认值为这两个值;其他情况下,默认值为Node。
- moduleSuffixes //指定模块的后缀名。
- newLine //设置换行符为CRLF(Windows)还是LF(Linux)
- noEmit //设置是否产生编译结果。如果不生成,TypeScript 编译就纯粹作为类型检查了。
- noEmitHelpers //设置在编译结果文件不插入 TypeScript 辅助函数,而是通过外部引入辅助函数来解决,比如 NPM 模块tslib。
- noEmitOnError //指定一旦编译报错,就不生成编译产物,默认为false。
- noFallthroughCasesInSwitch //设置是否对没有break语句(或者return和throw语句)的 switch 分支报错,即case代码里面必须有终结语句(比如break)
- noImplicitAny //设置当一个表达式没有明确的类型描述、且编译器无法推断出具体类型时,是否允许将它推断为any类型。它是一个布尔值,默认为true,即只要推断出any类型就报错。
- noImplicitReturns //设置是否要求函数任何情况下都必须返回一个值,即函数必须有return语句。
- noImplicitThis //设置如果this被推断为any类型是否报错。
- noUnusedLocals //设置是否允许未使用的局部变量。
- noUnusedParameters //设置是否允许未使用的函数参数。
- outDir //指定编译产物的存放目录。如果不指定,编译出来的.js文件存放在对应的.ts文件的相同位置。
- outFile //设置将所有非模块的全局文件,编译在同一个文件里面。它只有在module属性为None、System、AMD时才生效,并且不能用来打包 CommonJS 或 ES6 模块。
- paths //设置模块名和模块路径的映射,也就是 TypeScript 如何导入require或imports语句加载的模块。paths基于baseUrl进行加载,所以必须同时设置后者。
- preserveConstEnums //将const enum结构保留下来,不替换成常量值。
- pretty //设置美化输出终端的编译信息,默认为true
- removeComments //移除 TypeScript 脚本里面的注释,默认为false。
- resolveJsonModule //允许 import 命令导入 JSON 文件。
- rootDir //设置源码脚本所在的目录,主要跟编译后的脚本结构有关。rootDir对应目录下的所有脚本,会成为输出目录里面的顶层脚本。
- rootDirs //把多个不同目录,合并成一个目虚拟目录,便于模块定位。
- sourceMap //设置编译时是否生成 SourceMap 文件。
- sourceRoot //在 SourceMap 里面设置 TypeScript 源文件的位置。
- strict //用来打开 TypeScript 的严格检查。它的值是一个布尔值,默认是关闭的。
- strictBindCallApply //设置是否对函数的call()、bind()、apply()这三个方法进行类型检查。如果不打开strictBindCallApply编译选项,编译器不会对以上三个方法进行类型检查,参数类型都是any,传入任何参数都不会产生编译错误。
- strictFunctionTypes //允许对函数更严格的参数检查。具体来说,如果函数 B 的参数是函数 A 参数的子类型,那么函数 B 不能替代函数 A。
- strictNullChecks //设置对null和undefined进行严格类型检查。如果打开strict属性,这一项就会自动设为true,否则为false。
- strictPropertyInitialization //设置类的实例属性都必须初始化,包括以下几种情况。设为undefined类型,显式初始化,构造函数中赋值。注意,使用该属性的同时,必须打开strictNullChecks。
- suppressExcessPropertyErrors //关闭对象字面量的多余参数的报错。
- target //指定编译产物的 JS 版本,编译出来的 JavaScript 代码的 ECMAScript 版本,比如es2021,默认是es3。可能取值:它可以取以下值:es3,es5,es6/es2015,es2016,es2017,es2018,es2019,es2020,es2021,es2022,esnext
- traceResolution //设置编译时,在终端输出模块解析的具体步骤。
- typeRoots //设置类型模块所在的目录,默认是node_modules/@types,该目录里面的模块会自动加入编译。一旦指定了该属性,就不会再用默认值node_modules/@types里面的类型模块。该属性的值是一个数组,数组的每个成员就是一个目录,它们的路径是相对于tsconfig.json位置。
- types //默认情况下,typeRoots目录下所有模块都会自动加入编译,如果指定了types属性,那么只有其中列出的模块才会自动加入编译。
- useUnknownInCatchVariables //设置catch语句捕获的try抛出的返回值类型,从any变成unknown。
21. tsc 是 TypeScript 官方的命令行编译器,用来检查代码,并将其编译成 JavaScript 代码。
- # 使用 tsconfig.json 的配置
- $ tsc
-
- # 只编译 index.ts
- $ tsc index.ts
-
- # 编译 src 目录的所有 .ts 文件
- $ tsc src/*.ts
-
- # 指定编译配置文件
- $ tsc --project tsconfig.production.json
-
- # 只生成类型声明文件,不编译出 JS 文件
- $ tsc index.js --declaration --emitDeclarationOnly
-
- # 多个 TS 文件编译成单个 JS 文件
- $ tsc app.ts util.ts --target esnext --outfile index.js
- --all:输出所有可用的参数。
-
- --allowJs:允许 TS 脚本加载 JS 模块,编译时将 JS 一起拷贝到输出目录。
-
- --allowUnreachableCode:如果 TS 脚本有不可能运行到的代码,不报错。
-
- --allowUnusedLabels:如果 TS 脚本有没有用到的标签,不报错。
-
- --alwaysStrict:总是在编译产物的头部添加use strict。
-
- --baseUrl:指定非相对位置的模块定位的基准 URL。
-
- --build:启用增量编译。
-
- --checkJs:对 JS 脚本进行类型检查。
-
- --declaration:为 TS 脚本生成一个类型生成文件。
-
- --declarationDir:指定生成的类型声明文件的所在目录。
-
- --declarationMap:为.d.ts文件生成 SourceMap 文件。
-
- --diagnostics:构建后输出编译性能信息。
-
- --emitBOM:在编译输出的 UTF-8 文件头部加上 BOM 标志。
-
- --emitDeclarationOnly:只编译输出类型声明文件,不输出 JS 文件。
-
- --esModuleInterop:更容易使用 import 命令加载 CommonJS 模块。
-
- --exactOptionalPropertyTypes:不允许将可选属性设置为undefined。
-
- --experimentalDecorators:支持早期的装饰器语法。
-
- --explainFiles:输出进行编译的文件信息。
-
- --forceConsistentCasingInFileNames:文件名大小写敏感,默认打开。
-
- --help:输出帮助信息。
-
- --importHelpers:从外部库(比如 tslib)输入辅助函数。
-
- --incremental:启用增量构建。
-
- --init:在当前目录创建一个全新的tsconfig.json文件,里面是预设的设置。
-
- --inlineSourceMap:SourceMap 信息嵌入 JS 文件,而不是生成独立的.js.map文件。
-
- --inlineSources:将 TypeScript 源码作为 SourceMap 嵌入编译出来的 JS 文件。
-
- --isolatedModules:确保每个模块能够独立编译,不依赖其他输入的模块。
-
- --jsx:设置如何处理 JSX 文件。
-
- --lib:设置目标环境需要哪些内置库的类型描述。
-
- --listEmittedFiles:编译后输出编译产物的文件名。
-
- --listFiles:编译过程中,列出读取的文件名。
-
- --listFilesOnly:列出编译所要处理的文件,然后停止编译。
-
- --locale:指定编译时输出的语言,不影响编译结果。
-
- --mapRoot:指定 SourceMap 文件的位置。
-
- --module:指定编译生成的模块格式。
-
- --moduleResolution:指定如何根据模块名找到模块的位置。
-
- --moduleSuffixes:指定模块文件的后缀名。
-
- --newLine:指定编译产物的换行符,可以设为crlf或者lf。
-
- --noEmit:不生成编译产物,只进行类型检查。
-
- --noEmitHelpers:不在编译产物中加入辅助函数。
-
- --noEmitOnError:一旦报错,就停止编译,没有编译产物。
-
- --noFallthroughCasesInSwitch:Switch 结构的case分支必须有终止语句(比如break)。
-
- --noImplicitAny:类型推断只要为any类型就报错。
-
- --noImplicitReturns:函数内部没有显式返回语句(比如return)就报错。
-
- --noImplicitThis:如果this关键字是any类型,就报错。
-
- --noImplicitUseStrict:编译产生的 JS 文件头部不添加use strict语句。
-
- --noResolve:不进行模块定位,除非该模块是由命令行传入。
-
- --noUnusedLocals:如果有未使用的局部变量就报错。
-
- --noUnusedParameters:如果有未使用的函数参数就报错。
-
- --outDir:指定编译产物的存放目录。
-
- --outFile:所有编译产物打包成一个指定文件。
-
- --preserveConstEnums:不将const enum结构在生成的代码中,替换成常量。
-
- --preserveWatchOutput: watch 模式下不清屏。
-
- --pretty:美化显示编译时的终端输出。这是默认值,但是可以关闭--pretty false。
-
- --project(或者-p):指定编译配置文件,或者该文件所在的目录。
-
- --removeComments:编译结果中移除代码注释。
-
- --resolveJsonModule:允许加载 JSON 文件。
-
- --rootDir:指定加载文件所在的根目录,该目录里面的目录结构会被复制到输出目录。
-
- --rootDirs:允许模块定位时,多个目录被当成一个虚拟目录。
-
- --skipDefaultLibCheck:跳过 TypeScript 内置类型声明文件的类型检查。
-
- --skipLibCheck:跳过.d.ts类型声明文件的类型检查。这样可以加快编译速度。
-
- --showConfig:终端输出编译配置信息,而不进行配置。
-
- --sourcemap:为编译产生的 JS 文件生成 SourceMap 文件(.map 文件)。
-
- --sourceRoot:指定 SourceMap 文件里面的 TypeScript 源码根目录位置。
-
- --strict:打开 TypeScript 严格检查模式。
-
- --strictBindCallApply:bind, call、apply 这三个函数的类型,匹配原始函数。
-
- --strictFunctionTypes:如果函数 B 的参数是函数 A 参数的子类型,那么函数 B 不能替代函数 A。
-
- --strictNullChecks:对null和undefined进行严格类型检查。
-
- --strictPropertyInitialization:类的属性必须进行初始值,但是允许在构造函数里面赋值。
-
- --suppressExcessPropertyErrors:关闭对象字面量的多余参数的报错。
-
- --target:指定编译出来的 JS 代码的版本,TypeScript 还会在编译时自动加入对应的库类型声明文件。
-
- --traceResolution:编译时在终端输出模块解析(moduleResolution)的具体步骤。
-
- --typeRoots:设置类型模块所在的目录,替代默认的node_modules/@types。
-
- --types:设置typeRoots目录下需要包括在编译之中的类型模块。
-
- --version:终端输出 tsc 的版本号。
-
- --watch(或者-w):进入观察模式,只要文件有修改,就会自动重新编译。