TypeScript1
TS的变量声明需要加上类型说明
e.g let age: number = 18;
注意:TypeScript 会忽略程序中出现的空格、制表符和换行符。
空格、制表符通常用来缩进代码,使代码易于阅读和理解。
数组
定义方式:e.g let x: number[] = [1,2,3];
或者使用数组泛型,Array<元素类型>
e.g let y: Array<number> = [1,2];
元组:其元素可以是不同的数据类型
定义方式:1)确定具体元素:let x = ['hello', 333];
2)不确定元素但确定元素个数: let x[string, number];
x = ['hello', 333] //这种定义方式元素的顺序不能乱,要与定义时元素类型顺序一致,元素个数也只能与定义时指定的元素个数相同
元组方法:
1)push() //在元组末尾添加元素(可添加多个),返回数组长度
2)pop() //删除元组的最后一个元素,返回被删除元素
元组更新,元组可以像数组一样通过直接访问下标来更新其元素
toFixed() 方法可把 Number 四舍五入为指定小数位数的数字 e.g 12.22.toFixed(1) // 12.2
any类型,是针对编程时类型不明确的变量使用的一种数据类型
变量被定义为any类型,则变量的数据可以为任意类型,该类型在编译时不会进行类型检查
void类型:它表示没有类型
JS中,Null 和 Undefined 是其他任何类型(包括 void)的子类型,可以赋值给其它类型
在TS严格校验空特性下,就可以使得null 和 undefined 只能被赋值给 void 或本身对应的类型,变量类型声明时可以用 | 来支持多种类型(null和undefined)
枚举类型
enum Color {Red, Green, Blue} //默认Red = 0, Green = 1, Blue = 2
enum Color {Red = 7 , Green, Blue=10} //可更改默认值, Green = 8
Never类型
never类型是任何类型的子类型,never可以赋值给任何类型;没有类型是never类型的子类型
在函数中,never类型通常表现为抛出异常或无法执行到终止点(例如无限循环)
Unknown类型:它是any类型对应的安全类型,只能赋值给unknown类型和any类型
JS 中number表示的最大整数为2^53 -1(Number.MAX_SAFE_INTEGER)
Bigint数据类型用来表示那些超出了number类型最大值的整数类型
使用方式:
const way1: bigint = 9007199254740991n;
const way2: bigint = Bigint(9007199254740991);
const way1: bigint = Bigint("9007199254740991");
接口
接口的属性:readonly //只读
? //可选属性,e.g name?: string;
any //任意属性,e.g [special: string]: any;
1、函数接口: e.g
interface getFunc {
(name: string, age: number):boolean;
}
2、可索引接口: e.g
interface stringArray {
[index: number]: string;
}
3、类类型接口: e.g
interface Person {
name: string;
getPersonInfo(age: number): string
}
用extends实现继承类,用implements实现接口
和类一样,接口也可以通过关键字extends相互继承
4、接口继承类
当一个接口继承了一个类类型时,它会继承类的成员但不包括其实现。当一个接口继承了一个拥有私有或保护的成员的类时,这个接口类型只能由这个类或其子类实现。
函数
在JS中所有的函数参数都是可选的,而在TS中,定义的参数都是必需要传入的参数,可以使用形参名后加?来使参数变得可选
class
在TS中,成员都默认是public的
protected:受保护,可以被自身以及其子类和父类访问
private:私有,只能被其定义所在的类访问
接口不包含成员的实现细节,而抽象类一般做为其它派生类的基类使用,可以包含其成员的实现细节,抽象类不能实例化
泛型
Partial: 将对象中属性改为可选属性
type Partial<T> = {
[P in keyof T]?: T[P];
}
keyof: 索引类型查询操作符 //keyof作用于泛型T上可以获取泛型T上所有public属性名构成的联合类型,不能得到私有类型的属性
e.g interface Person{
name: string;
sex: string;
age:number;
}
type person = keyof Person
等同于
type person = "name" | "sex" | "age"
in //遍历类型T中的属性名
? //将该属性变为可选属性
P 保存属性名的临时变量,T[P]为返回类型
Pick:获取对象中的属性的类型
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
e.g
interface Person{
name: string;
age: number;
}
type person1 = Pick<Person, 'name'>; //person1 === {name: string}
Record: 改变属性的类型
type Record< K extends keyof any, T> = {
[P in K]: T;
};
e.g
type person2 = Record<'name' | 'age', string> // person2 === {name: string, age: string}
类型断言:
let str: any = 'hello world';
1、let strLength: number = (<string>str).length; //用<>
2、let strLength: number = (str as string).length; //用as
联合类型:
如果一个值是联合类型,只能访问此联合类型的所有类型里的共有的成员
条件类型:
T extends U ? X : Y
若T是U的子类型,则类型为X, 否则类型为Y。若无法确定T是否是U的子类型,则类型为X|Y
关键字
is //用于指定参数类型
e.g const isString = (str: unknown): str is string => typeof str === 'string'
infer //用来推断一个变量
ReturnType<数据类型> //传入什么数据类型就返回什么数据类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
装饰器
装饰器执行的顺序:
属性装饰器->方法装饰器->方法参数装饰器->访问器装饰器->类装饰器
如果有两个同类的装饰器,先执行后面一个
Reflect
Reflect.defineMetadata('元数据名','元数据的值', 目标对象) //定义元数据
metadata = Reflect.getMetadata('元数据名', 目标对象) //返回元数据的值
通过Reflect.metadata装饰器对类添加元数据
e.g
@Reflect.metada('元数据名', '元数据的值')
class Post{ }
然后通过Reflect.getMetadata来获取元数据的值
命名空间
命名空间被视为内部模块,命名空间内的接口或者类等对象必须要经过导出后,外部文件才能使用
命名空间可以拆分,但不同代码块的命名空间之间的变量不能互相访问
命名空间可以嵌套,嵌套层数 不限,但要在外面访问被嵌套的命名空间,必须要使用'export'
命名空间与类的合并
合并名称相同的命名空间与类:
1、命名空间的成员必须导出,合并后的类才能访问
2、命名空间内导出的成员,相当于合并后的类的静态属性
3、命名空间要放在类的定义的后面

浙公网安备 33010602011771号