个人总结,如有错误望指正。
一句话简单暴力理解TS:
TypeScript就是在你声明的变量的后面加一个“:”,冒号后面写你限定的类型,将动态类型语言js规范为一个静态类型语言ts,使其在编译期间就发现可能存在的错误,减少后续因类型原因导致的错误
TypeScript的安装:
npm install -g typescript
从npm全局安装ts
tsc -v
通过tsc查看当前安装的ts版本
hello函数 by ts 与简单类型声明
const hello = (name : string) => {
console.log(`hello ${name}`)
}
hello('kasnars')
undefined是所有类型的子类型,所有类型都可以被赋值为undefined
let num : number = undefined
将变量设为any 可以任意改变类型和调用方法 但是频繁使用any会丧失ts本身的意义,并且any类型无法触发ide的方法提示
let anydata : any = 4
anydata = 'is string'
anydata = true
联合类型:
将变量声明为多种类型,不再为单一类型。用 ' | ' 分隔多种类型
let unitype : number | string = 123
unitype = 'string'
定义数组类型
对数组内的内容进行限制,例如下例将数组内容限制为number
let arrnum : number[] = [1,2,3]
arrnum.push(4)
Tuple元组:类似于将限定了类型的多个数组组合到一起(参考pytho元组)限定几个就只能写几个,下列限定了两个数据,如果出现了第三个数据则会报错
let userinfo : [string, number] = ['kasnars', 20]
userinfo = ['lyx', 18]
interface接口:
1.对对象形状进行描述
2.对类进行抽象
类似与事先规定好了一种类型,可以在定义类的时候直接调用这个接口来声明类型,而不用再去声明string之类
interface Person{
name: string;
age: number;
}
let kasnars : Person = {
name: 'kasnars',
age: '20'
}
注意:interface的声明中用分号分隔,不是对象中的逗号
一般情况下interface定义了几个类型,调用这个interface的对象也得有几个类型,除非在某一个类型的后面加上问号,加上问号后在调用这个接口进行定义时,有问号的类型为可选项,例如
interface Person{
name: string;
age?: number;
}
let kasnars : Person = {
name: 'kasnars'
}
对接口里的属性添加readonly属性可以将这个属性变为只读,在初次被赋值后不可再被修改,类似与一个const常量,但是const是用于限制一个变量的,readonly用于限制对象里的一个属性。
interface Person{
readonly id : number;
name:string;
}
函数声明:
ts函数声明时需要给函数的参数和返回值设定类型,实例如下:
function add (x: number,y: number):number{
return x + y
}
let result = add(1,2)
函数的参数和接口一样,可以设置一个可选项,同样在可选的参数后加一个问号
注意:可选参数必须放在传入参数中的最后
function add(x:number,y:number,z?number):number{
...
}
将函数赋值给一个变量或常量时,这个常量也会被带上类型,例:
const add = function(x:number,y:number):number{
return x+y
}
//这里的add已经拥有了被定义的类型,需要将add函数赋值给别人时,也需要遵守类型对应的原则
const add2 :(x:number,y:number) => number = add
注意:ts中冒号之后的都是在定义它的类型,故上面代码中add2冒号后面和等于号前面的一长串都是在规定add2的类型,另外上面的=>并非es6中的箭头函数,而是ts用于声明函数返回值类型的标志
ts中类的声明:
与其他一样,简单的类声明只需要在参数的后面规定类型即可
class People{
name: string;
constructor(name: string){
this.name = name
}
run(){
return : `${this.name} is running`
}
}
const lyx = new People('lyx')
cnosole.log(lyx.run())
ts中类的修饰:(与java类似)
public 公共属性
class People{
public name: string;
constructor(name: string){
this.name = name
}
run(){
return : `${this.name} is running`
}
}
private 私有属性,仅本身可以调用,实例和子类皆不可调用
class People{
private name: string;
constructor(name: string){
this.name = name
}
run(){
return : `${this.name} is running`
}
}
protected 保护属性,本身和自己子类可以调用,其他人不可调用,子类需要用extends和super去继承
class People{
protected name: string;
constructor(name: string){
this.name = name
}
run(){
return : `${this.name} is running`
}
}
readonly 只读属性,所有人可读但不可更改
class People{
readonly name: string;
constructor(name: string){
this.name = name
}
run(){
return : `${this.name} is running`
}
}
ts中类与接口结合:
1.接口之间可以互相继承
2.接口可以用来对类进行修饰,类中必须用有接口规定的方法
interface Radio{
switchRadio():void
}
interface Battery{
checkBatteryStatus():void
}
interface RadioWithBattery extends Radio{
checkBatteryStatus():void
}
上例实现了接口的继承,在使用接口对class进行限制时要使用implements关键字
class car implements Radio{
switchRadio(){}
}
class tellphone implements RadioWithBattery{
switchRadio(){}
checkBatteryStatus(){}
}
enum枚举:
enum direction{
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
console.log(direction.Up)
//up
//在enum前面加const可使其变为常量枚举,可以提升性能 但并不是所有枚举都适合被声明为常量
泛型:
在定义类型的时候不预先规定其类型,而是在其调用时决定他的类型
简单泛型案例(利用和T对类型进行占位)
function echo <T> (any: T):T{
return any
}
const result = echo('123')
//此时result为string类型
const num = echo(123)
//此时num为number类型
将多个类型声明为泛型
function swap<T> (tuple:[T,U]):[U,T]{
return [tuple[1],tuple[0]]
}
将接口和泛型结合,通过接口来强制使泛型内拥有某种方法,例
function uselength <T> (arg:T):T{
console.log(arg.length)
return arg.length
}
//此时代码会报错,因为uselength是一个泛型,不确定传入的数据到底是什么类型,不确定是否能够使用length属性
此时我们需要用接口去定义一个length属性,然后在定义泛型时使用这个接口,使这个泛型必须拥有此接口规定的属性
interface Ilength{
length: number
}
function uselength <T extends Ilength> (arg:T):T{
console.log(arg.length)
return arg.length
}
//此时代码不会报错
泛型与类结合,实例化时指定所需类型
class queue <T>{
private data = []
push(arg:T){
...
}
}
const num = new queue<number>()
//此时num为number属性 可以调用number的方法
接口与泛型结合,在调用接口时规定所需要的类型
interface keypair<T,U>{
key:T;
value:U;
}
const key1:keypair<string,number> = {key:'kasnars',value:'20'}
类型别名:利用关键字type给复杂的类型取一个别名简化代码
type numplus = (x: number, y: number) => number
function add(x: number, y:number) : number{
return x + y
}
const add2: numplus = add
类型断言 type assertion
在给一个参数声明为联合类型时,编译器无法确定传进来的参数是其中哪一种,所以默认只能使用两种类型的公共方法,而类型断言则直接给他指定为其中的一种,从而让其使用对应类型的方法,例:
function getlength(x: string | number) : number{
//此时函数x内只能使用string和number都有的公共方法,无法调用属性特有的方法
}
使用类型断言去指定一个类型,向编译器证明,你比他更懂这段代码
进行类型断言有两种方法
1.使用as关键字
const str = x as string
//此时将x指定为了string类型,从而可以去使用string类型的方法
2.使用(<type>arg)
格式
(<string>x).length
//此时被括号包括的x被断言为了string类型,可以使用string下的所有方法
注意:类型断言不是类型转换,只能断言为联合类型中有的类型,断言为其他类型会报错,例如上面getlength函数中把x断言为布尔值是不可行的
声明文件:
引用外部库时对外部库进行类型定义,例
declare var jQuery:(selector : string) => any
一般将这种声明文件放到外部一个xxxx.d.ts 以.d.ts结尾的文件中,编译器会自动去解析.d.ts后缀里的声明
一般在使用其他库和ts结合时只需下载官方对应的声明文件即可