当一个类型Y可以被赋值给另一个类型X时,我们就可以说类型X兼容类型Y ---------X兼容Y:X(目标类型)= Y(源类型)
ts允许我们把一些类型不同的变量相互赋值(虽然再某种程度上讲产生了不可靠行为,但增加了语言的灵活性)
配置项"strictNullChecks": false, null就是字符串的子类型
let s:string = "123";
s = null
类型兼容性的例子广泛存在与接口,函数,类中
1.接口兼容性,
体现了ts的类型检查原则---鸭式变形法---源类型必须具备目标类型的必要属性
总结:接口之间的兼容时候,成员少的兼容成员多的
interface XX{
a:any;
b:any;
}
interface YY{
a:any;
b:any;
c:any;
}
let xx :XX = {a:1,b:2};
let yy :YY = {a:1,b:2,c:3};
xx = yy
yy = xx // 报错yy不兼容xx
2.函数兼容性
1).参数个数 ---参数多的可以兼容少的
type Hander = (a:number,b:number)=>void;
function hof(hander:Hander){
return hander
};
let hander1 = (value:number)=>{}
hof(hander1);
let hander2 = (value:number,value2:number,value3:number)=>{}
hof(hander2) //错误
2).可选参数和剩余参数
固定参数兼容可选参数和剩余参数,可选参数不能兼容固定参数和剩余参数,剩余参数可以兼容固定参数和可选参数
let a = (p1:number,p2:number)=>{};
let b = (p1?:number,p2?:number)=>{}
let c = (...arg:number[])=>{}
a =b;
a =c;
b = a //不兼容
b = c //不兼容
c = b
c = a
3)参数类型 ---多的可以兼容少的 (与接口之间兼容关系相反)
可以把对象拆分成3个参数就是参数多的兼容参数少的-------也就是参数个数的兼容了
let hander3 = (value:string)=>{}
hof(hander3);
interface point3{
x:number;
y:number;
z:number;
}
interface point2{
x:number;
y:number;
}
let p2d = (value:point2)=>{ }
let p3d = (value:point3)=>{ }
p2d=p3d //会报错
p3d=p2d
4)函数返回值------少的可以兼容多的 (目标函数的返回值类型必须与原函数的返回值类型相同或为其子集)
let f = function(){ return {a:"alice",sex:"women"} }
let g = function(){ return {a:"alice"} };
f=g//会报错,因为多的兼容少的,与接口类型的兼容一样
g=f
5)函数重载 ----- 目标函数参数个数多于或者等于源函数参数个数
列表中的函数是目标函数,具体的实现是源函数
3.枚举
数字和枚举可以相互兼容,枚举与枚举间不兼容
4.类
类的构造函数和静态成员不参与比较,当类中有私有成员时,两个类不兼容,类与子类可以
5.泛型
1)泛型接口------在两个泛型参数只有类型不相同时,只有在泛型参数使用时才影响
2)泛型函数