letage: number =16;letname: string ='zhangsan';letflag: boolean =false;leta:null=null;letb:undefined=undefined;letc: symbol =Symbol();leto: symbol =Symbol();
//定义枚举类型//Up-->Right 值0,1,2,3enum Des {Up,Down,Left,Right}functionchage(dire: Des){}//访问枚举成员chage(Des.Up)//设置枚举成员的值//Up-->Right 值10,11,12,13enum Des {Up=10,Down,Left,Right}enum Des {Up=10,Down=12,Left=14,Right=16}//字符串枚举(没有自增行为,因此每个成员必须要有初始值)enum Des {Up='Up',Down='Down',Left='Left',Right='Right'}
类型别名(自定义类型)
类型别名可以为任意类型起别名,当同一复杂类型被多次使用,可以起类型别名,简化使用
//关键字type
type CustomType =(number | string)[]letarr1: CustomType =[1.'2',3]
接口
当一个对象类型被多次使用时,一般会使用接口来描述对象的类型
使用interface关键字来声明接口
因为没一行只有一个属性,所以属性类型没有;
//接口interfaceIPerson{name: string
age: number
sai(name: string):void}letperson: IPerson ={name:'zhangsan',age:19,say(){}}//interface接口和type类型别名都可以给对象指定类型,但接口只能为对象指定类型,类型别名可以为任意类型指定别名
type IPerson1{name: string
age: number
sai(name: string):void}
接口继承(extends)
interfacePerson{name: string
age: number
}// IPerson继承了Person中所有的属性interfaceIPersonextendsPerson{sai(name: string):void}
类型推断
//(1)声明变量并初始化时let age =16//(2)决定函数返回值时functionadd(num1: number,num2: number){return num1+num2}
let p ={x:1,y:2}//point:后面是类型的声明,也就是类型上下文functionforp(point:typeof p){}forp({x:10,y:100})//可以查看对象属性的类型leta:typeof p.x;//a的类型为numberletret:typeofforp({x:10,y:100})//报错,不可以查看函数调用的类型
class类型
classPerson{//属性name: string //声明但不赋值
age =16//声明并赋值//构造函数不需要返回值类型constructor(name: string,age: number){this.name = name
this.age = age
}//方法sayi(n:number):void{
console.log(n)}}const p =newPerson()//代表当前常量p的类型是Person
classPoint{x:number,y:number}classPoint2{x:number,y:number}constp: Point =newPoint2()//正常,因为只检查Point和Point2的结构是否相同
classPoint{a:number,b:number}//xclassPoint2{a:number,b:number,c:number}//y//对于对象类型来说,y的成员至少与x相同,则x兼容y(成员多的可以给成员少的赋值)constp: Point =newPoint2()
接口的类型兼容性(和class一样)
interfacePoint{a:number,b:number}//xinterfacePoint2{a:number,b:number,c:number}//yconstp: Point = Point2
//class和interface之间也可以兼容classPoint2{a:number,b:number,c:number}//yconstp: Point =newPoint3()
函数之间的兼容性
参数个数:参数少的可以赋值给参数多的,因为js中可以省略用不到的参数
type F1=(a:number)=>void
type F2=(a:number,b:number)=>voidletf1:F1letf2:F2=f1
参数类型:相同位置的参数类型(原始类型)要相同或(对象类型)要兼容
// (原始类型)要相同
type F1=(a:number)=>void
type F2=(a:number)=>voidletf1:F1letf2:F2=f1
// (对象类型)要兼容// 从接口角度看是冲突的,技巧,将对象拆开,把每一个属性看做一个个参数。interfacePoint{a:number,b:number}interfacePoint2{a:number,b:number,c:number}
type F1=(a:Point)=>void
type F2=(a:Point2)=>voidletf1:F1letf2:F2=f1
返回值类型:只关注返回值类型本身即可,返回类型(原始类型)要相同或(对象类型)要兼容
// (原始类型)
type F1=()=> number
type F2=()=> number
letf1:F1letf2:F2=f1
// (对象类型:按照对象的兼容规则)成员多的赋值给成员少的
type F1=()=>{a:number,b:number}
type F2=()=>{a:number,b:number,c:number}letf1:F1letf2:F2
f1=f2
交叉类型
交叉类型 & :功能类似接口继承,用于组合多个类型为一个类型常用于对象
interfacePoint{fn:(a:number)=>number}interfacePoint2{b:number;fn:(a:string)=> string}
type Per = Point & Point2
// Per可以理解为{fn(a:number|string)=>string}letobj: Per ={fn(number){}b:2}
泛型
创建泛型函数
function id(value:Type):Type{return value}
在函数名称后面加 <> 尖括号中添加类型变量
常用于函数、接口、class
function id<Type>(value:Type):Type{return value}const num = id<number>(10)const num =id(10)//<类型>可以省略,因为有类型参数推断机制const str = id<string>('a')
泛型约束
指定更加具体的类型
添加约束
function id<Type>(value:Type[]):Type[]{return value.length //就可以访问value的length属性了}