typescript思维导图
2022-06-13 21:00:17 2 举报
AI智能生成
typescript 基础类型,内置类型,类型推断,interface和type别名以及声明文件和typescript配置
作者其他创作
大纲/内容
基础
string
number
boolean
boolean类型本身其实只是true|false 联合类型的别名
null和undefined
对于null和undefined的检查取决于stricNullChecks是否开启
如果关闭,那么ts不再检查null和undefined的赋值和从他们中取值的合法性
如果打开,那么ts会检查从对应类型中取值和赋值的合法性
非空断言!
在变量后面使用!实际上是一种断言,它表示这个变量不是null和undefiend
function liveDangerously(x?: number | null) {
// No error
console.log(x!.toFixed());
}
// No error
console.log(x!.toFixed());
}
any
任意类型
数组
number[] number 组成的数组
string[] string组成的数组
bigint
symbol
unknown
和any类似,但是它更安全,因为unknown不能做任何事。
function f1(a: any) {
a.b(); // OK
}
function f2(a: unknown) {
a.b();
Object is of type 'unknown'.
}
a.b(); // OK
}
function f2(a: unknown) {
a.b();
Object is of type 'unknown'.
}
函数
参数类型
function greet(name:string){console.log(name.toUpperCase())}
返回值类型
function getFavoriteNumber(): number {
return 26;
}
return 26;
}
对象类型
interface Obj{
name:string,
// 并不是所有人都有girdFriend
// 加?表示可选属性
girdFriend?:string
}
name:string,
// 并不是所有人都有girdFriend
// 加?表示可选属性
girdFriend?:string
}
联合类型(Union Types)
定义联合类型
string|number,表示类型是string或者number其中的一个
使用联合类型
ts规定只有在对联合体的每个成员都有效的情况下才允许操作
const stringOrNumber:string|number = 1;
stringOrNumber.toUpperCase()//报错因为number类型不具备toUpperCase方法
stringOrNumber.toUpperCase()//报错因为number类型不具备toUpperCase方法
类型别名
type Point={
x:number,
y:number,
}
x:number,
y:number,
}
type ID=string|number
接口
接口声明是命名对象类型的另一种方式
接口interface和类型别名type的区别
他们非常相似,几乎所有的interface特性对于type都是可用的
唯一的不同点在于,interfacce是可重新定义添加属性的,type 不能被重新定义
他们定义扩展的形式也不同,interface可以extends,type使用&
interface 只能定义对象类型,type可以对原始类型重命名
可以一直使用interface,直到不符合需求再使用type
类型断言
as 类型断言来指定更具体的类型
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
也可以使用尖括号
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
注意: 再tsx文件中尖括号被认为是标签而报错
as 类型断言一般是断言为更具体或更不具体的类型,如果断言为完全不可能的类型会报错
const n = 11 as string//报错,不充分重叠
解决:先断言为any、unknown,再断言为想要的类型
const dd = '11' as unknown as number
!
叹号放在变量后面,表示这个变量不会是undefined和null
字面类型
字面类型的推断可能会根据定义变量的形式决定
const s = 'abcd'
s被推断为'abcd'类型,因为const之后,s不可能再变化
let s = 'abcd'
s被推断为string类型,因为let之后,s可能发生变化
单一的字面类型意义不大,更多的情况下是使用联合类型,说明变量可能存在的多种情况
function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}
//alignment 可能是left、right、center其中之一
// ...
}
//alignment 可能是left、right、center其中之一
字面推理
ts在推理对象类型时,不会给对象的属性指定为字面类型
const req = { url: "https://example.com", method: "GET" };
这个类型被认为是
const req: {
url: string;
method: string;
}
const req: {
url: string;
method: string;
}
于是以下赋值可能被判断为错:
function handleRequest(url:string, method:'GET'|'POST'){//.....}
handleRequest(req.url, req.method);
Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
function handleRequest(url:string, method:'GET'|'POST'){//.....}
handleRequest(req.url, req.method);
Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
转换为字面类型
1. 使用类型断言,把类型指定为某个类型
// Change 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
2. 使用as const把整个对象转换成字面类型
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
handleRequest(req.url, req.method);
枚举类型
使用enum定义枚举
枚举具有特殊性,他是真实存在的数据,不仅仅是类型
收窄
类型谓词is
interface Fish{
swim:()=>void
}
interface Bird{
fly:()=>void
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
swim:()=>void
}
interface Bird{
fly:()=>void
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
pet is Fish 表示函数返回pet是不是一个Fish类型
let pet = getSmallPet();
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
判断isFish之后,ts会直到类型是不是一个Fish
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
判断isFish之后,ts会直到类型是不是一个Fish
never
never可以赋值给任何类型,没有类型可以分配给never(除了它自己)
从未观察到的值
函数function
函数类型表达式
function greeter(fn: (a: string) => void) {
fn("Hello, World");
}
function printToConsole(s: string) {
console.log(s);
}
greeter(printToConsole);
fn("Hello, World");
}
function printToConsole(s: string) {
console.log(s);
}
greeter(printToConsole);
语法的(a: string) => void意思是“一个带有一个参数的函数,名为a,类型为字符串,没有返回值”。
调用签名
函数除了可调用之外还可以具有属性。
type DescribableFunction = {
description: string;
(someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6));
}
description: string;
(someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6));
}
注意这里的fn可以访问description属性,也可以直接被调用
(someArg: number): boolean; 这里用的是冒号:,而不是=>
构造签名
构造函数可以使用new 关键字创建对象
interface SomeObj{
a:number
}
interface NewFn{
new ():SomeObj
}
let newFn:NewFn
const obj = new newFn;
a:number
}
interface NewFn{
new ():SomeObj
}
let newFn:NewFn
const obj = new newFn;
ts中使用new关键字表示这个函数可以被new出来,且可以标识new出的对象是SomeObj
通用函数
function firstElement<Type>(arr: Type[]): Type | undefined {
return arr[0];
}
return arr[0];
}
// s is of type 'string'
const s = firstElement(["a", "b", "c"]);
// n is of type 'number'
const n = firstElement([1, 2, 3]);
// u is of type undefined
const u = firstElement([]);
const s = firstElement(["a", "b", "c"]);
// n is of type 'number'
const n = firstElement([1, 2, 3]);
// u is of type undefined
const u = firstElement([]);
给函数添加一个类型参数Type,并且在参数和返回值处使用它,我们就在返回和参数之间创建了联系。这种泛型可以告诉ts返回是什么类型
注意,如果类型参数Type只在函数签名的一个地方出现,那么很大可能它是不需要的,出现这种情况需要重新考虑是否需要类型参数
function greet<Str extends string>(s: Str) {
console.log("Hello, " + s);
}
console.log("Hello, " + s);
}
// 根本无需Str类型参数
function greet(s: string) {
console.log("Hello, " + s);
}
function greet(s: string) {
console.log("Hello, " + s);
}
推断
function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {
return arr.map(func);
}
// Parameter 'n' is of type 'string'
// 'parsed' is of type 'number[]'
const parsed = map(["1", "2", "3"], (n) => parseInt(n));
return arr.map(func);
}
// Parameter 'n' is of type 'string'
// 'parsed' is of type 'number[]'
const parsed = map(["1", "2", "3"], (n) => parseInt(n));
ts会自动根据输入的类型判断Input,因此函数直到n参数是string
指定类型参数
function combine<Type>(arr1: Type[], arr2: Type[]): Type[] {
return arr1.concat(arr2);
}
return arr1.concat(arr2);
}
一个组合数组的函数
const arr = combine([1, 2, 3], ["hello"]);
Type 'string' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
这么使用会报错,因为类型推断Type是number[],再给出string会报错
这时候可以手动指定类型的参数
const arr = combine<string | number>([1, 2, 3], ["hello"]);
约束
我们可以给函数类型参数加约束
function longest<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a;
} else {
return b;
}
}
if (a.length >= b.length) {
return a;
} else {
return b;
}
}
这个类型说明了输入需要含有length属性
const longerArray = longest([1, 2], [1, 2, 3]);
// longerString is of type 'alice' | 'bob'
const longerString = longest("alice", "bob");
// Error! Numbers don't have a 'length' property
const notOK = longest(10, 100);
// longerString is of type 'alice' | 'bob'
const longerString = longest("alice", "bob");
// Error! Numbers don't have a 'length' property
const notOK = longest(10, 100);
可选参数和默认参数
使用问号?添加可选参数
function f(x?: number) {
// ...
}
f(); // OK
f(10); // OK
// ...
}
f(); // OK
f(10); // OK
使用赋值添加默认参数,和js一样
function f(x = 10) {
// ...
}
// ...
}
函数重载
js可以使用不同个数的参数和类型进行调用,我们可以编写多个重载类型签名,同时编写一个具有兼容签名的函数实现。兼容的函数实现签名叫做实现签名,这个实现签名不能直接调用、不能从外部看到
function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}
const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
const d3 = makeDate(1, 3);
No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}
const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
const d3 = makeDate(1, 3);
No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.
function fn(x: string): void;
function fn() {
// ...
}
// Expected to be able to call with zero arguments
fn();
Expected 1 arguments, but got 0.
function fn() {
// ...
}
// Expected to be able to call with zero arguments
fn();
Expected 1 arguments, but got 0.
实现签名不会被看到
注意:尽可能使用联合类型而不是重载
// 一个返回字符串或数组长度的函数
function len(s: string): number;
function len(arr: any[]): number;
function len(x: any) {
return x.length;
}
function len(s: string): number;
function len(arr: any[]): number;
function len(x: any) {
return x.length;
}
// 这个调用就会报错
len(Math.random() > 0.5 ? "hello" : [0]);
len(Math.random() > 0.5 ? "hello" : [0]);
他的问题在于如果参数是string|number类型就会报错,因为没有函数重载的参数是string|number
// 这是良好的非重载版本
function len(x: any[] | string) {
return x.length;
}
function len(x: any[] | string) {
return x.length;
}
this
指定函数中的this指向
interface User{
admin:boolean
}
interface DB {
filterUsers(filter: (this: User) => boolean): User[];
}
let db:DB
const admins = db.filterUsers(function () {
return this.admin;
});
admin:boolean
}
interface DB {
filterUsers(filter: (this: User) => boolean): User[];
}
let db:DB
const admins = db.filterUsers(function () {
return this.admin;
});
这里filterUser的回调中的this就被认为是User
rest函数参数
使用...可以吧rest参数放在所有其他参数后面,用法基本同js
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x);
}
// 'a' gets value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);
return m.map((x) => n * x);
}
// 'a' gets value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);
ypeScript 并不假定数组是不可变的
// Inferred type is number[] -- "an array with zero or more numbers",
// not specifically two numbers
const args = [8, 5];
const angle = Math.atan2(...args);
A spread argument must either have a tuple type or be passed to a rest parameter.
// not specifically two numbers
const args = [8, 5];
const angle = Math.atan2(...args);
A spread argument must either have a tuple type or be passed to a rest parameter.
解决:
// Inferred as 2-length tuple
// 手动指定为字面类型
const args = [8, 5] as const;
// OK
const angle = Math.atan2(...args);
// 手动指定为字面类型
const args = [8, 5] as const;
// OK
const angle = Math.atan2(...args);
返回void
定义函数,返回类型(包括void),实现的时候必须返回指定类型
// 以下两种会报错
function fVOid1(): void {
return true;
}
const fVoid2 = function (): void {
return true;
};
function fVOid1(): void {
return true;
}
const fVoid2 = function (): void {
return true;
};
指定变量的返回类型为函数,函数返回值为void,不会强制返回void
type voidFunc = () => void;
const f1: voidFunc = () => {
return true;
};
const f2: voidFunc = () => true;
const f3: voidFunc = function () {
return true;
};
const f1: voidFunc = () => {
return true;
};
const f2: voidFunc = () => true;
const f3: voidFunc = function () {
return true;
};
voidFunc说明需要返回void
f1返回了true并不会导致报错
f1返回了true并不会导致报错
object
可以通过接口interface或者别名type来定义
属性修饰符
可选属性?
interface PaintOptions {
shape: Shape;
xPos?: number;
yPos?: number;
}
shape: Shape;
xPos?: number;
yPos?: number;
}
只读属性readonly
interface SomeType {
readonly prop: string;
}
readonly prop: string;
}
如果对prop赋值将会报错
interface Home {
readonly resident: { name: string; age: number };
}
虽然不能直接修改resident,但是可以修改name、age
readonly resident: { name: string; age: number };
}
虽然不能直接修改resident,但是可以修改name、age
readonlyTypeScript在检查这些类型是否兼容时不会考虑两种类型的属性是否存在
interface Person {
name: string;
age: number;
}
interface ReadonlyPerson {
readonly name: string;
readonly age: number;
}
let writablePerson: Person = {
name: "Person McPersonface",
age: 42,
};
// 可以吧writablePerson赋值给ReadonlyPerson类型的变量
let readonlyPerson: ReadonlyPerson = writablePerson;
console.log(readonlyPerson.age); // prints '42'
writablePerson.age++;
console.log(readonlyPerson.age); // prints '43'
name: string;
age: number;
}
interface ReadonlyPerson {
readonly name: string;
readonly age: number;
}
let writablePerson: Person = {
name: "Person McPersonface",
age: 42,
};
// 可以吧writablePerson赋值给ReadonlyPerson类型的变量
let readonlyPerson: ReadonlyPerson = writablePerson;
console.log(readonlyPerson.age); // prints '42'
writablePerson.age++;
console.log(readonlyPerson.age); // prints '43'
索引签名
interface StringArray {
[index: number]: string;
}
[index: number]: string;
}
这个类型说明索引为number时,值是string
索引签名属性类型必须是字符串或数字
强制所有属性匹配其返回类型。
interface NumberDictionary {
[index: string]: number;
length: number; // ok
name: string;
Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
}
[index: string]: number;
length: number; // ok
name: string;
Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
}
扩展类型
给一个基础类型扩展额外的属性
interface BasicAddress {
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
interface AddressWithUnit extends BasicAddress {
unit: string;
}
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
interface AddressWithUnit extends BasicAddress {
unit: string;
}
extends关键字可以有效地从其他类型复制成员,并添加任何新成员
从多个类型扩展
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
interface ColorfulCircle extends Colorful, Circle {}
const cc: ColorfulCircle = {
color: "red",
radius: 42,
};
color: string;
}
interface Circle {
radius: number;
}
interface ColorfulCircle extends Colorful, Circle {}
const cc: ColorfulCircle = {
color: "red",
radius: 42,
};
合并类型
使用&定义合并类型,用于组合现有的对象类型
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
type ColorfulCircle = Colorful & Circle;
color: string;
}
interface Circle {
radius: number;
}
type ColorfulCircle = Colorful & Circle;
相交Colorful并Circle生成了一个新类型,它包含Colorful 和 Circle的所有成员。
&和extends 没有太大的区别,他们的区别还是type和interface的区别,1.如何对待类型冲突2.能不能定义原始类型
数组类型
string[]是Array<string>的简写形式,表示包含string类型的数组
readonly string[]是ReadonlyArray<string>的简写形式,表示包含string类型的只读数组,不可以改变数组中的元素
注意string[]和readonly string[]不是可以双向赋值的
let x:readonly string[]=[]
let y:string[] = []
x=y;// 没有问题
y=x;// 报错
// 简单说就是可以收紧,把可变的变成readonly的,不能放宽
let y:string[] = []
x=y;// 没有问题
y=x;// 报错
// 简单说就是可以收紧,把可变的变成readonly的,不能放宽
元组类型
元组是一种特殊的数组,它确切的知道包含多少个元素,每个特定位置包含哪些类型
type StringNumberPair = [string, number]
第一个元素是string,第二个元素是number,没有第三个元素,引用第三个元素报错
它甚至等同于
interface StringNumberPair {
// specialized properties
length: 2;
0: string;
1: number;
// Other 'Array<string | number>' members...
slice(start?: number, end?: number): Array<string | number>;
}
// specialized properties
length: 2;
0: string;
1: number;
// Other 'Array<string | number>' members...
slice(start?: number, end?: number): Array<string | number>;
}
元组剩余元素
type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];
StringNumberBooleans描述一个元组,其前两个元素分别是string和number,但后面可以有任意数量的booleans.
StringBooleansNumber描述一个元组,它的第一个元素是string,然后是任意数量的booleans 并以 a 结尾number。
BooleansStringNumber描述了一个元组,其起始元素是任意数量的booleans 并以 a 结尾,string然后是 a number。
StringBooleansNumber描述一个元组,它的第一个元素是string,然后是任意数量的booleans 并以 a 结尾number。
BooleansStringNumber描述了一个元组,其起始元素是任意数量的booleans 并以 a 结尾,string然后是 a number。
readonly [string, number]
只读的元组
类型操作
泛型
function identity<Type>(arg: Type): Type {
return arg;
}
return arg;
}
向标识函数添加了一个类型变量Type,可以再次使用Type作为返回类型
interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
(arg: Type): Type;
}
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
定义一个GenericldentityFn类型,它有一个泛型Type,可以传递给它的type参数number,
这样identity函数的参数就变成了number,返回也是number
对象函数调用写法参考函数 调用签名 call sign
泛型类
泛型类再类名称后面添加一个尖括号,其中就是泛型参数列表
class GenericNumber<NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
// 静态成员不能使用类的泛型,这一行会报错
static minus(x:NumType:y:NumType)=>NumType
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
// 静态成员不能使用类的泛型,这一行会报错
static minus(x:NumType:y:NumType)=>NumType
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
注意:泛型类仅在其实例方面而不是其静态方面是通用的,因此在使用类时,静态成员不能使用类的类型参数。
泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
泛型通过extends约束arg必须含有length属性
keyof
对于对象类型生成其键的字符串或数字的联合类型
type Point = {x:number,y:number;}
type P = keyof Point; // x|y
type P = keyof Point; // x|y
type Mapish = { [k: string]: boolean };
type M = keyof Mapish;// 结果是string|number
type M = keyof Mapish;// 结果是string|number
这是因为在js中,key总是会被转成字符串,obj[0]和obj['0']是一样的
typeof
js本身具有一个typeof运算符,用来获取类型
ts中的typeof运算符,可以在类型上下文中使用它引用变量或属性的类型
let s = 'hello'
let n:typeof s;// n:string
let n:typeof s;// n:string
// 获取复杂对象的类型
type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>; // K:boolean
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<f>;// 报错,因为f是真是的函数,而非类型
type P = ReturnType<typeof f>; // 获取f函数的类型传递给ReturnType
type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>; // K:boolean
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<f>;// 报错,因为f是真是的函数,而非类型
type P = ReturnType<typeof f>; // 获取f函数的类型传递给ReturnType
限制
typeof只能用于标识符(即变量名)或其属性上是合法的
索引访问
可以使用索引来查找对象类型上的特性属性
type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];
type Age = Person["age"];
可以使用keyof、联合类型获取其他类型
type I1 = Person["age" | "name"];// type I1 = string | number
type I2 = Person[keyof Person];// type I2 = string | number | boolean
type I2 = Person[keyof Person];// type I2 = string | number | boolean
通过number索引获取数组上的类型
type Arr= [0,1,'a','b']
type Test = Arr[number] //[0,1,'a','b']
type F = Arr[0] // 0
type Test = Arr[number] //[0,1,'a','b']
type F = Arr[0] // 0
const Arr= [0,1,'a','b']
type Test = typeof Arr[number]//number|string
注意以上两者的不同
type Test = typeof Arr[number]//number|string
注意以上两者的不同
条件类型
通过extends来判断左侧的类型是否可分配给右侧的类型
type NameOrId<T extends number | string> = T extends number
? IdLabel
: NameLabel;
function createLabel<T extends number | string>(idOrName: T): NameOrId<T> {
throw "unimplemented";
}
let a = createLabel("typescript");//let a: NameLabel
let b = createLabel(2.8);// let b: IdLabel
let c = createLabel(Math.random() ? "hello" : 42);//let c: NameLabel | IdLabel
? IdLabel
: NameLabel;
function createLabel<T extends number | string>(idOrName: T): NameOrId<T> {
throw "unimplemented";
}
let a = createLabel("typescript");//let a: NameLabel
let b = createLabel(2.8);// let b: IdLabel
let c = createLabel(Math.random() ? "hello" : 42);//let c: NameLabel | IdLabel
条件类型约束
type MessageOf<T extends {message:string}>=T['message']// 通过 extends 约束,ts就知道T应该还有一个message属性
在条件类型中推断infer
infer用来推断在extends的真是分支上的类型
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
? Return
: never;
type Num = GetReturnType<() => number>;// type Num = number
type Str = GetReturnType<(x: string) => string>;// type Str = string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;// type Bools = boolean[]
? Return
: never;
type Num = GetReturnType<() => number>;// type Num = number
type Str = GetReturnType<(x: string) => string>;// type Str = string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;// type Bools = boolean[]
分布式条件类型
type ToArray<Type> = Type extends any ? Type[] : never;
type StrArrOrNumArr = ToArray<string | number>;// string[]|number[]
type StrArrOrNumArr = ToArray<string | number>;// string[]|number[]
例子中,Type如果是union类型,那么union类型中的每一个成员都会执行一次extends,这是默认的行为
如果不想获得这种分布性,可以使用中括号吧关键字每一侧括起来
type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never;
// 'StrArrOrNumArr' is no longer a union.
type StrArrOrNumArr = ToArrayNonDist<string | number>;// type StrArrOrNumArr = (string | number)[]
// 注意结果和上一个例子的不同
// 'StrArrOrNumArr' is no longer a union.
type StrArrOrNumArr = ToArrayNonDist<string | number>;// type StrArrOrNumArr = (string | number)[]
// 注意结果和上一个例子的不同
映射类型
可以遍历对象类型,并生成一个新的对象类型
type FeatureFlags = {
darkMode: () => void;
newUserProfile: () => void;
};
type FeatureOptions = OptionsFlags<FeatureFlags>;
结果: type FeatureOptions = {
darkMode: boolean;
newUserProfile: boolean;
}
darkMode: () => void;
newUserProfile: () => void;
};
type FeatureOptions = OptionsFlags<FeatureFlags>;
结果: type FeatureOptions = {
darkMode: boolean;
newUserProfile: boolean;
}
映射修饰符
可以使用+-来,来添加、删除可变性(readonly)和可选性(?)
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};
type LockedAccount = {
readonly id: string;
readonly name: string;
};
type UnlockedAccount = CreateMutable<LockedAccount>;
结果:type UnlockedAccount = {
id: string;
name: string;
}
-readonly [Property in keyof Type]: Type[Property];
};
type LockedAccount = {
readonly id: string;
readonly name: string;
};
type UnlockedAccount = CreateMutable<LockedAccount>;
结果:type UnlockedAccount = {
id: string;
name: string;
}
// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type MaybeUser = {
id: string;
name?: string;
age?: number;
};
type User = Concrete<MaybeUser>;
结果:type User = {
id: string;
name: string;
age: number;
}
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type MaybeUser = {
id: string;
name?: string;
age?: number;
};
type User = Concrete<MaybeUser>;
结果:type User = {
id: string;
name: string;
age: number;
}
通过as重新映射
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
interface Person {
name: string;
age: number;
location: string;
}
type LazyPerson = Getters<Person>;
结果为:
type LazyPerson = {
getName: () => string;
getAge: () => number;
getLocation: () => string;
}
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
interface Person {
name: string;
age: number;
location: string;
}
type LazyPerson = Getters<Person>;
结果为:
type LazyPerson = {
getName: () => string;
getAge: () => number;
getLocation: () => string;
}
过滤某些键
// Remove the 'kind' property
type RemoveKindField<Type> = {
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};
interface Circle {
kind: "circle";
radius: number;
}
type KindlessCircle = RemoveKindField<Circle>;
结果为:
type KindlessCircle = {
radius: number;
}
type RemoveKindField<Type> = {
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};
interface Circle {
kind: "circle";
radius: number;
}
type KindlessCircle = RemoveKindField<Circle>;
结果为:
type KindlessCircle = {
radius: number;
}
模板文字类型
和js的模板字符串同样的用法,用于生成新的字符串类型
在插值位置使用联合union类型时,每个联合成员表示的每个可能的字符串的集合
type EmailLocaleIDs = "welcome_email" | "email_heading";
type FooterLocaleIDs = "footer_title" | "footer_sendoff";
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
// 结果:
type AllLocaleIDs = "welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id"
type FooterLocaleIDs = "footer_title" | "footer_sendoff";
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
// 结果:
type AllLocaleIDs = "welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id"
对于模板文字中的每个插值位置,联合是交叉相乘的:
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
type Lang = "en" | "ja" | "pt";
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;
结果为:共有3*4=12中可能
type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"
type Lang = "en" | "ja" | "pt";
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;
结果为:共有3*4=12中可能
type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"
内置字符串操作类型
Uppercase(StringType)
每个字符串大写
type Greet = 'Hello, world';
type ShoutyGreet = Uppercase<Greet>;// HELLO,WORLD
type ShoutyGreet = Uppercase<Greet>;// HELLO,WORLD
Lowercase<StringType>
每个字符串小写
type Greet = 'Hello,world'
type QuietGreet = Lowercase<Greet>;// hello,world
type QuietGreet = Lowercase<Greet>;// hello,world
Capitalize<StringType>
首字母大写
type LowercaseGreeting = "hello, world";
type Greeting = Capitalize<LowercaseGreeting>;// Hello,world
type Greeting = Capitalize<LowercaseGreeting>;// Hello,world
Uncapitialize<StringType>
首字母小写
type UppercaseGreeting = "HELLO WORLD";
type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>;// hELLO WORLD
type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>;// hELLO WORLD
class类
ts中class基本用法
implements
实现一个interface,implements之后不是真的已经实现了,这个关键字是用来检测class是否实现了interface中的属性和方法
extends
继承,子类会具有基类的所有属性和方法
只声明字段类型
可以为子类声明字段类型为更精确地类型,而不影响js的运行时
成员可见性
public
默认可见的修饰符
protected
受保护的成员,仅对声明他们的类的子类可见
private
不允许子类访问成员
这个仅仅是ts类型的检查,并不是真的私有变量
js中的私有使用#来定义,这使得#定义的私有变量硬私有,完全不能被访问到
静态成员static
静态成员也能使用可见性修饰符
静态成员也能被继承
泛型类
this
引用当前类的类型
返回值使用this is来收窄类型范围
参数属性
在构造函数上加上可见性修饰符public、protected、private、readonly,可以吧构造函数参数转化为同名的类属性
抽象类
abstract
定义抽象类,不能直接被实例化,它是用来被继承的基类
模块
es模块
可以使用与ES模块相同的语法导入、导出ts类型
import type
只能导入ts类型
内联type导入
内置类型
Partial<Type>
返回一个给定类型所有子集的类型,即字段都变成可选
Required<Type>
所有属性必填
Readonly<Type>
所有属性只读
Object.freeze 冻结函数的类型:
function freeze<Type>(obj: Type): Readonly<Type>;
function freeze<Type>(obj: Type): Readonly<Type>;
Record<Keys, Type>
构造一个对象类型,键为keys,值为Type
Pick<Type, Keys>
从Type中获取某些keys来构造新类型
Omit<Type, Keys>
从Type中删除某些keys来构造新类型
Exclude<UnionType, ExcludedMembers>
从联合类型(union)中去除一些类型之后来构造新类型
Extract<Type, Union>
获取两个联合类型的交集
NonNullable<Type>
从type中去除null和undefined
Parameters<Type>
从函数类型的参数中使用的类型来获取元组型类型
ConstructorParameters<Type>
从构造函数类型的类型构造元组或数组类型。它产生一个包含所有参数类型的元组类型
ReturnType<Type>
构造一个由函数的返回类型组成的类型
InstanceType<Type>
由实例类型构成的类型
ThisParameterType<Type>
提取函数类型的this参数的类型,如果没有参数则为unknown
OmitThisParameter<Type>
从函数类型中删除this的类型和泛型之后的函数类型
ThisType<Type>
用作上下文this的标记,它标记this的类型是什么
注意tsconfig.json必须开启noImplicitThis(非隐式this)才能使用
Uppercase<StringType>
类型字符串大写
Lowercase<StringType>
类型字符串小写
Capitalize<StringType>
类型字符串首字母大写
Uncapitalize<StringType>
类型字符串首字母小写
枚举
使用enum关键字定义枚举,枚举是运行时真实存在的对象
数字枚举
// 从3开始依次递增
enum Direction {
Up=3,
down,
right,
next
}
Direction.down;// 4
enum Direction {
Up=3,
down,
right,
next
}
Direction.down;// 4
// 从中间开始初始化
enum Direction {
Up,
down=9,
right,
next
}
Direction.Up// 0
Direction.right // 10
enum Direction {
Up,
down=9,
right,
next
}
Direction.Up// 0
Direction.right // 10
也可以不指定开始的值,那么将从0开始递增
如果初始化值不是数字,那么之后的所有枚举值都要手动指定
字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
异构枚举(数字和字符串混合)
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
No = 0,
Yes = "YES",
}
非必要,不要这么做
枚举是真实存在的对象
enum BB{
a,
b,
c,
d,
}
console.log(BB)
// {'0':'a', '1':'b', '2':'c', '3':'d', 'a':0, 'b':1, 'c':2, 'd':3}
console.log(BB.c) // 2
consolelog(BB[0]) //'a'
a,
b,
c,
d,
}
console.log(BB)
// {'0':'a', '1':'b', '2':'c', '3':'d', 'a':0, 'b':1, 'c':2, 'd':3}
console.log(BB.c) // 2
consolelog(BB[0]) //'a'
枚举的键的类型
type Keys = keyof typeof BB
注意Keys是一个类型,不是一个真实存在的值
反向映射
对于数字类型的枚举会有反向映射的现象
enum BB{
a,
b,
c,
d,
}
console.log(BB)
// {'0':'a', '1':'b', '2':'c', '3':'d', 'a':0, 'b':1, 'c':2, 'd':3}
console.log(BB.c) // 2
consolelog(BB[0]) //'a'
a,
b,
c,
d,
}
console.log(BB)
// {'0':'a', '1':'b', '2':'c', '3':'d', 'a':0, 'b':1, 'c':2, 'd':3}
console.log(BB.c) // 2
consolelog(BB[0]) //'a'
对于字符串类型的枚举,没有反向映射
cosnt枚举值
使用cosnt enum来定义
const enum{
A=1,
B=A*2
}
A=1,
B=A*2
}
他们在编译期间会被完全删除,只能用索引来访问
ts使用一个tsconfig.json管理项目选项
root field
files
指定包含在程序中的文件列表,如果文件不存在会报错
extends
继承的配置文件
不能继承references
include
指定程序加载的文件名或正则
** 匹配任何嵌套到任何级别的目录
* 匹配零个或多个字符
? 匹配任何一个字符
* 匹配零个或多个字符
? 匹配任何一个字符
如果匹配规则没有指定文件后缀,那么默认加载(.ts, .tsx, .d.ts, .js, .jsx(如果allowJs为true))
exclude
指定程序应该跳过的文件名或正则
它会排除include中包含的文件,但是import等文件自身引用的文件还是会被加载。
references
引用另一个项目
compilerOption
allowUnreachableCode
由于无法访问代码产生的错误不会有警告信息
无法访问的代码会被忽略
不会对不可访问的代码做出建议
allowUnusedLabels
不许没有使用的标签
alwaysStrict
文件总是在严格模式下解析
exactOptionalPropertyTypes
对于可选属性 ? 具有更精确更严格的规则
开启之后不能把undefined赋值给可选属性
noFallthroughCasesInSwitch
在switch语句中确保每个字句都包含break或者return,否则报错
noImplicitAny
隐式推断为any时报错
noImplicitOverride
必须使用override 来表示子类中的重载函数
noImplicitReturns
确保所有路径都有返回值
noImplicitThis
隐式的this表达式上发出警告
noPropertyAccessFromIndexSignature
访问属性可以通过点语法(obj.key)和索引语法(obj["key"])
开启这个标志之后,不允许使用点语法访问不确定存在的属性
noUncheckedIndexedAccess
访问可能不存在的属性时,添加undefined到类型中
noUnusedLocals
未使用的变量报错
noUnusedParameters
未使用的函数参数报错
strict
严格的,打开它相当于启用所有严格模式系列选项
即开头为strict的选项
strictBindCallApply
严格绑定,call、bind、apply设置之后ts将检查函数参数类型是否正确
不开启的话,参数都是any,返回也是any
strictFunctonTypes
更正确的检查函数参数
strictNullChecks
严格空检查
关闭时,不会检查null和undefined
strictPropertyInitialization
严格的属性初始化 声明了的类属性如果没有在构造函数中初始化会报错(直接指定了值或者类型可能为undefiend除外)
useUnknowInCatchVariables
catch捕获的err变量标志为unknow
allowUmdGlobalAccess
允许从模块内部方位作为全局变量引入的UMD。比如知道loadsh始终在运行时能够使用,但不用通过导入访问
baseUrl
设置允许解析的基本目录
module
设置程序的模块系统
noResolve
不会检查import和<reference>指令加载文件
paths
声明相对于baseUrl如何解析import或者require中的导入
resolveJsonModule
允许导入带有.json后缀的模块
rootDir
根目录,指定输出目录。默认是所有非声明输入文件的最长公共路径
MyProj
├── tsconfig.json
├── core
│ ├── a.ts
│ ├── b.ts
│ ├── sub
│ │ ├── c.ts
├── types.d.ts
├── tsconfig.json
├── core
│ ├── a.ts
│ ├── b.ts
│ ├── sub
│ │ ├── c.ts
├── types.d.ts
默认情况下输出为
MyProj
├── dist
│ ├── a.js
│ ├── b.js
│ ├── sub
│ │ ├── c.js
MyProj
├── dist
│ ├── a.js
│ ├── b.js
│ ├── sub
│ │ ├── c.js
如果把rootDir定义为'.',那么输出目录为
MyProj
├── dist
│ ├── core
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── sub
│ │ │ ├── c.js
MyProj
├── dist
│ ├── core
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── sub
│ │ │ ├── c.js
rootDirs
通知编译器有许多目录充当单个根,允许编译器解析这些目录,并把他们合并到一个目录中
typeRoots
默认情况下所有可见的@type都包含在编译中,例如node_module/@type,./node_module/@type,../../node_module/@type
指定了typeRoots之后仅包含指定的路径
types
仅列出包包含在全局范围内
{
"compilerOptions": {
"types": ["node", "jest", "express"]
}
}
"compilerOptions": {
"types": ["node", "jest", "express"]
}
}
该tsconfig.json文件将仅包括./node_modules/@types/node,./node_modules/@types/jest和./node_modules/@types/express. 下面的其他包node_modules/@types/*将不包括在内。
declaration
为每个ts或js文件生成.d.ts文件
declarationDir
声明文件的根目录
declarationMap
.d.ts为映射回原始.ts源文件生成映射,这允许vscode等编辑器,使用go to definition功能转到原始文件
downLevelIteration
支持更准确的实现就js运行中的新概念,如for of,[...arr],Symbol.Iterator
emitBom
控制ts在输出文件时是否发出字节顺序标记BOM
emitDeclarationOnly
只输出.d.ts不输出.js 文件
importHelpers
对于一些降级操作,ts会使用一些辅助函数来进行。如果在不同模块中使用相同的函数会导致代码重复
打开选项之后这些辅助函数会从tslib模块中导入,不再重复
importsNotUsedAsValues
remove ,删除导入但未未使用的module
preserve 保留导入的值或类型
error 保留所有导入,但当导入仅作为类型时报错
inlineSourceMap
设置之后,会替换.js.map文件。ts会把sourcemap文件放到js之中
inlineSources
设置之后,ts会把.ts的源文件作为string放到sourcemap中
mapRoot
指定ts解析器应该定位映射文件而不是生成的位置
newLine
发出文件的行尾序列使用什么
noEmit
不要发出编译器输出文件,这位babel等其他工具腾出空间来处理ts
noEmitHelpers
不导出辅助函数
noEmitError
如果报错,那么不会输出编译之后的文件
outDir
输出目录
outFile
如果指定,那么所有全局文件都会解析到这个文件中
preserveConstEnums
不要删除const Enum的声明
preserveValueImports
保留值得导入
removeComments
ts转换为js的时候删除所有注释
sourceMap
生成sourceMap(.js.map)文件
sourceRoot
指定ts文件的相对位置
stripInternal
不对具有@internal 的jsDoc注释的代码生成代码
allowJs
允许在项目中导入js文件
checkJs
在js 文件中报告错误
maxNodeModuleJsDepth
node_modules搜索和加载js文件的最大深度
disableSizeLimit
删除ts内存限制
plugins
插件列表
allowSyntheticDefaultImports
允许从没有设置默认导出的模块中默认导入
esModuleInterop
ts对于import的编译规则发生一些变化
开启之后如果模块没有默认导出,那么会把内容都放到default中一份
forceConsistentCasingInFileNames
在文件名中强制使用一致的大小写
isolatedModule
将每个文件作为单独的模块(与“ts.transpileModule”类似)
preserveSymlinks
不把符号链接解析为其真实路径;将符号链接文件视为真正的文件。
charset
输入文件的字符集。
keyofStringsOnly
此标志将keyof类型运算符更改为返回string,而不是string | number应用于具有字符串索引签名的类型时。
noImplicitUseStrict
模块输出中不包含 "use strict"指令。
noStrictGenericChecks
禁用在函数类型里对泛型签名进行严格检查。
out
弃用。使用 --outFile 代替。
suppressExcessPropertyErrors
阻止对对象字面量的额外属性检查。
suppressImplicitAnyIndexErrors
阻止 --noImplicitAny对缺少索引签名的索引对象报错
emitDecoratorMetadata
给源码里的装饰器声明加上设计类型元数据。
experimentalDecorators
启用实验性的ES装饰器。
jsx
在 .tsx文件里支持JSX: "React"或 "Preserve"
jsxFactory
指定生成目标为react JSX时,使用的JSX工厂函数
jsxFragmentFactory
指定生成jsx的fragmen时,使用的工厂
lib
编译过程中需要引入的库文件的列表。
noLib
不包含默认的库文件
reactNamespace
当目标为生成 "react" JSX时,指定 createElement和 __spread的调用对象
target
指定ECMAScript目标版本 "ES3"(默认), "ES5", "ES6"/ "ES2015", "ES2016", "ES2017"或 "ESNext"。
useDefineForClassFields
ts批准class之前就已经有类字段,打开这个标志会把类的行为切换到最新的ECMA标准
diagnostics
显示诊断信息。
explainFiles
打印文件被ts编译的查找过程
extendedDiagnostics
显示详细的诊段信息。可以打印编译时间等
generateCpuProfile
只能通过CLI使用,可以打印出CPU配置
listEmittedFiles
打印出编译后生成文件的名字。
listFiles
编译过程中打印文件名。
traceResolution
生成模块解析日志信息
composite
开启时,如果rootDir没有设置,则设置为tsconfig.json的目录,所有文件必须由include或files指定,declaration为true
disableReferencedProjectLoad
禁用所有项目的自动加载
disableSolutionSearching
在复合ts项目中,如果项目很大,那么查找功能会非常慢,开启它会提高响应能力
disableSourceOfProjectReferenceRedirect
incremental
告诉 TypeScript 将上次编译的项目图信息保存到磁盘上存储的文件中。这会在编译输出所在的文件夹中创建一系列.tsbuildinfo文件。您的 JavaScript 在运行时不使用它们,可以安全地删除它们
tsBuildInfoFile
此设置允许您指定用于存储增量编译信息的文件作为复合项目的一部分,从而可以更快地构建更大的 TypeScript 代码库
noErrorTruncation
不截断错误消息。
preserveWatchOutput
保留watch模式下过时的控制台输出。
pretty
给错误和消息设置样式,使用颜色和上下文。
skipDefaultLibCheck
忽略 库的默认声明文件的类型检查。改为使用skipLibCheck。
skipLibCheck
忽略所有的声明文件( *.d.ts)的类型检查。
watchOptions
watchFile
如何查看单个文件的策略。
fixedPollingInterval:以固定的间隔每秒检查每个文件的更改数次。
priorityPollingInterval:每秒检查每个文件几次更改,但使用启发式检查某些类型的文件的频率低于其他文件。
dynamicPriorityPolling:使用动态队列,不经常检查修改频率较低的文件。
useFsEvents(默认):尝试使用操作系统/文件系统的本机事件进行文件更改。
useFsEventsOnParentDirectory: 尝试使用操作系统/文件系统的原生事件来监听文件父目录的变化
priorityPollingInterval:每秒检查每个文件几次更改,但使用启发式检查某些类型的文件的频率低于其他文件。
dynamicPriorityPolling:使用动态队列,不经常检查修改频率较低的文件。
useFsEvents(默认):尝试使用操作系统/文件系统的本机事件进行文件更改。
useFsEventsOnParentDirectory: 尝试使用操作系统/文件系统的原生事件来监听文件父目录的变化
watchDirectory
缺少递归文件监视功能的系统下如何监视整个目录树的策略。
fixedPollingInterval:以固定的间隔每秒检查每个目录的更改数次。
dynamicPriorityPolling: 使用动态队列,不太频繁地检查不经常修改的目录。
useFsEvents(默认):尝试使用操作系统/文件系统的本机事件进行目录更改。
dynamicPriorityPolling: 使用动态队列,不太频繁地检查不经常修改的目录。
useFsEvents(默认):尝试使用操作系统/文件系统的本机事件进行目录更改。
fallbackPolling
使用文件系统事件时,此选项指定当系统用完本机文件观察程序和/或不支持本机文件观察程序时使用的轮询策略。
fixedPollingInterval:以固定的间隔每秒检查每个文件的更改数次。
priorityPollingInterval:每秒检查每个文件几次更改,但使用启发式检查某些类型的文件的频率低于其他文件。
dynamicPriorityPolling:使用动态队列,不经常检查修改频率较低的文件。
synchronousWatchDirectory:禁用对目录的延迟观看。node_modules当可能同时发生大量文件更改(例如执行npm install)时,延迟监视很有用,但您可能希望使用此标志禁用它以用于一些不太常见的设置。
priorityPollingInterval:每秒检查每个文件几次更改,但使用启发式检查某些类型的文件的频率低于其他文件。
dynamicPriorityPolling:使用动态队列,不经常检查修改频率较低的文件。
synchronousWatchDirectory:禁用对目录的延迟观看。node_modules当可能同时发生大量文件更改(例如执行npm install)时,延迟监视很有用,但您可能希望使用此标志禁用它以用于一些不太常见的设置。
synchronousWatchDirectory
在本机不支持递归观察的平台上同步调用回调并更新目录观察者的状态。而不是给一个小的超时以允许对文件进行潜在的多次编辑。
excludeDirectories
可以使用excludeFiles来减少watch的文件。
excludeFiles
可以使用excludeFiles来减少watch的文件
typeAcquisition
enable
提供在js项目中禁用类型获取的配置(false)
include
如果js项目中ts需要额外的信息知道全局类型的依赖,可以使用include
exclude
提供用于禁用 JavaScript 项目中某个模块的类型获取的配置
disableFilenameBasedTypeAcquisition
TypeScript 的类型获取可以根据项目中的文件名推断应该添加哪些类型
声明文件
当我们的项目使用第三方库,而这个库没有ts类型时,我们可以编写声明来帮助ts判断类型,一般来说我们会把库的声明语句都放到一个单独文件中,这个文件就是声明文件,声明文件以.d.ts作为后缀
有些库已经提供了ts类型,有些是社区提供了ts声明。社区的声明一般使用npm install @types/xxx来下载即可
引用声明文件的方法
和ts文件放在同一目录下
在tsconfig.json中使用include或者files文件添加声明文件的路径
声明文件的类型
全局变量
decalare var
定义全局变量
同样的可以使用declare const,declare let 差异和const、var、let相同
decalare function
定义全局函数
decalare class
定义全局class
decalare enum
定义全局枚举
decalare namespace
定义一个命名空间,命名空间下可以有子类型
interface 接口和type 类型别名
npm包
export
声明文件中含有export 就说明是一个模块声明文件
export namespace
export default
export =
UMD库(既可以通过scripte标签引入又可以import导入的库)
export as namespace 可以把声明文件变成全局可用
decalar global 扩展全局变量
模块插件(导入一个库之后会改变另一个模块的原有结构)
decalare module
0 条评论
下一页