进阶
一、高级类型
1.联合类型
希望一个变量可以支持多个类型,可以在声明的时候|来联合类型声明
//联合类型
let unkown:string|number = 18
unkown = "unkown"
2.类型别名
定义一个新类型,
首字符大写
type NewType = string | number
//使用NewType类型,代表这个变量可以是 string或者number
let aVsr:NewType = 2
aVsr = "anc"
//定义复杂的数组
let arr: NewType[] = [1,'33']
type 与 interface的区别?
type 使用交叉类型&来继承,interface 使用extends 来继承
3.交叉类型
对对象类型进行扩展
//交叉类型
interface student {
name:string
age:number
}
type midstudent = student & { grade:number }
let p1:midstudent = {
name:"cici",
age:18,
grade:9
}
4.类型保护
类型保护是在执行运行时检查的一种表达式,确保该类型的执行范围。
当不确定变量到底是联合类型变量中的哪个类型时,就只能访问其所有类型的公有属性和方法
//比如获取长度的时候,如果不进行类型保护。直接返回val.length
//会报错 ,number 没有 length属性
const getLen = (val:string|number):number => {
return (typeof val === "string") ? val.length :val
}
常用的手法:
- xx in 对象
typeof判断变量类型,返回值有undefined/boolean/string/number/object等instanceof判断对象是否为某个对象的实例
5.类型断言
值 as 类型
类型断言只能断言成联合类型中某一个类型,用来避免编译报错。
const getLen2 = (val:string|number):number => {
let str = val as string
if(str.length){
return str.length
}else{
let number = val as number
return number.toString.length
}
}
console.log(getLen2(2))
二、泛型 


上述中讲到的关于多态、类型保护、类型断言之类的,都是在应用在传入参数时候的类型不确定的情况下的一种处理方式。但是ts实现了一种泛型。
泛型主要作用于定义函数、接口、类的时候,不预先指定具体类型,在使用的时候再指定类型。
<T>,在定义的时候像参数一样传入,然后原封不动的输出。
1.定义泛型
1.基本使用
变量<T>,在<...>中写类型参数,一般用T来表示。其中,T像一个占位符.
// 定义泛型
function consoleFn<T>(arg:T):T {
console.log(arg)
return arg
}
//使用
consoleFn<string>("hello")
//类型推论,省略了<number>
consoleFn(123456)
2.默认参数
//默认参数
function defaultArg<T = number> (arg : T) : T{
return arg
}
3.多个参数
//多个参数
function someArgs <T,U> (val:T,arg:U):[T,U]{
return [val,arg]
}
console.log(someArgs(222,333))
2、约束泛型
虽然解决了同类型输入输入的问题,但是如果使用到一些类型所独有的属性时候,就会报错。比如数组的length属性。如下:
function getLength<T>(arg:T) : T {
console.log(arg.length) //报错
return arg
}
那么需要约束这泛型一定有·length·属性。
//约束
interface Ilength {
length:number
}
function getLength<T extends Ilength>(arg:T) : T {
console.log(arg.length)
return arg
}
这样约定之后,使用arg.length 的时候不会报错。但是使用该函数的时候,需要传入带有length属性的变量。
泛型无法约束
static
3.泛型应用 - 定义一个栈
//定义一个栈
class Stack<T>{
private data:T[] = []
push(val:T){
this.data.push(val)
}
pop(){
this.data.pop()
}
}
let s1 = new Stack<number>()
// s1.push("32") //push字符串会报错
s1.push(12)