Typescript
将动态类型语言的JavaScript变为了静态类型语言。主要是使用了一个tsc编译器。
在终端中使用tsc命令可以将ts文件转化为相应的js文件
tsc xxx.ts
原始数据类型和Any类型
ES中有7种原始类型和一个Object
TS中的Any类型允许赋值为任何类型
数组和元组
数组
TS这里的数组是对元素的类型进行了约束的,类型写在[]前。
let arrNum:number[] = [1,2,3]
这里需要注意的是,伪数组都是有自己特定的类型的
元组
那么在TS中如何将不同类型的元素合并为一个数组呢?
可以使用元组。
以下代码需要注意的是,赋值的数组也必须是第一个元素类型为string,第二个为number的,但是push的时候是两个中的一个即可。
let arr:[string,number] = ['st',123]
user.push(xxx) xxx只能是这两种类型中的一种
interface接口
- 对对象的形状进行描述
像是一个约束好的模板,定义了一个新的类型
属性后加?表示可选属性
interfa Person {
name: string;
age: number;
power?: string;
}
let man:Person = {xxx}
readonly 只读属性关键字(readonly用于属性,const用于变量)
interface xxx {
readonly attribute:xxx
}
function函数
在TS中可以约定输入约定输出
在TS中,冒号后面都是在声明类型,和实际的代码逻辑没什么关系
这一整个就是一个函数类型
{x:number,y:number,z?:number} => number
也可以使用?来表示可选,可选参数后面不可添加必选参数
函数声明
function add (x:number,y:number,z?:number):number {
return x+y
}
函数表达式
箭头函数
const add = (x:number,y:number,z?:number):number => {
return x+y
}
普通
const add = function (x:number,y:number,z?:number):number {
return x+y
}
用另一个函数名进行赋值声明的时候,要用箭头来表示函数的结果类型
函数的声明(第二处处的箭头不是箭头函数,是对函数返回值类型的声明)
const add = (x:number,y:number):number => {return x+y}
const add2:(x:number,y:number)=>number = add
这里也可以使用接口interface
interface ISum {
(x:number,y:number,z?:number):number
}
let add2:ISum = add
关于函数的类型
如果后面跟的是个具体函数,那么这个时候类型是写在参数那个位置的,结果的类型就是用‘:’来表示。如果不是具体函数那就是‘=>’
类型的推论
会根据赋值来给没有定类型的变量定一个类型
let str= 'str'
联合类型 union types
这个时候访问属性就得访问两个类型的共有属性了,不然会报错
let numberOrString:number | string
如果我们真的需要使用一个类型的属性,就要使用类型断言(as)来默认类型然后再使用他的属性
function func(input:string|number):number {
const str = input as string
}
使用typeof来判断类型,在各个分支中TS会智能判断当前的类型
类Class
之前学习ES语法时,说是静态的属性还是不能用static关键字来定义的,但是在TS里面可以了。
TS中对类的加强(public、private、protected、readonly)
protected的属性子类可以访问到
类和接口
当两个类不是父类子类关系,但是有相同内容的时候,就可以使用接口。
关键字:implements
interface Radio {
switchRadio(trigger:boolean):void;
}
class Car implements Radio {
switchRadio(trigger:boolean) {}
}
class Cellphone implements Radio {
switchRadio(trigger:boolean) {}
}
要加多个接口的时候加逗号即可,接口和接口之间也可以通过extends来实现继承(只不过这里不用super)
这个例子中,implements了RadioWithBattert接口后就要写两个方法了(checkBattertStatus()和switchRadio(trigger:boolean))
interface RadioWithBattert extends Radio {
checkBattertStatus():void
}
枚举
对于一系列常量的表示
关键字enum
enum Direction {
Up,
Down,
Left,
Right
}
输出Direction.Up的值为0
可以反向映射
输出Direction[0]的值为Up
对枚举项进行数字复制,后续的枚举项会递增
enum Direction {
Up = 10,
Down,
Left,
Right
}
在JS中的转换
在JS中赋值操作的返回值是所赋的那个值,所以这种双向映射可以这么写
Direction[Direction['Up']=0] = 'Up';
在enum前面加个const就是一个常量枚举,这个时候JS转换的时候就会简化很多,是直接翻译成结果,而不会把全部枚举给翻译过去。
泛型(难点,重点)
相当于一个占位符,在定义函数、接口、类的时候不事先定义类型。
以下代码就可以实现输入和输出的类型一致,如果使用any就不能实现一致,如果事先定类型满足所有类型就很麻烦。
function echo<T>(arg:T):T {
return arg
}
也可以使用多个类型结合
function swap<T,U>(xxxxxx){}
约束泛型
关键字extends(和继承一样)
对泛型进行约束,只能输入包含该属性的类型的数据
interface IWithLength {
length:number
}
function echoWithLength<T extends IWithLength>(arg:T):T {}
在类和接口中的使用
这样来约束类型会更加灵活,使得类和接口可以复用。
class Queue<T> {
push(item:T){}
pop():T{}
}
const queue = new Queue<number>()
interfacee KeyPair<T,U> {
key:T
value:U
}
类型别名,字面量,交叉类型
类型别名type aliase
关键字type
有时候声明一个函数或者声明一个符合的类型,如果多次使用每次都写一遍会很繁琐,这个时候就可以使用类型别名
let func:(a:number,b:string) => string
使用type
type FuncType = (a:number,b:string) => string
let func:FuncType
type StrOrNumber = String | Number
let data:StrOrNumber = '123'
字面量
如果用字符串或者数字来当一个变量的类型限制,那么该变量就只能等于这个字符串或者数字了。这在常量的定义中非常好用。
type Direction = 'Up'|'Down'|'Left'|'Right'
let toWhere:Direction = 此处就只能等于前面那四个值了
交叉类型
关键字&
是使用type扩展对象的一种方式,很像用|来复合类型,但这里是对属性的约束。
interface IName {
name: string
}
type IPerson = IName & { age: number }
let person: IPerson = { name: 'hello', age: 12}
声明文件
使用第三方文件的方法
关键字declare告诉编译器该文件已经在别处定义了,不要报错。
只要有一个TS文件(需要用名字来命名文件名,比如说jQuery.ts)声明了类型约束,其他文件使用时就会使用这个类型。
内置类型
在全局作用域中存在的对象
比如说Array、Date、Math等