类的兼容性
class Point {x:number ; y:number}
class Point2D{x:number ; y:number}
const p:Point = new Point2D()
//不会报错
解释:
1.Point和Point2D是两个不同的类。
2.变量p的类型被标注为Point类型,但是它的值却是Point2D的实例,并且没有类型错误。
3.因为TS是结构化类型系统,值检查Point和Point2D的结构是否相同(即x与y两个属性是否相同)
注意:
在Nominal Type System中(比如c#,java等)它们是不同的,类型无法兼容
成员多的可以赋值给少的
class Point {x:number ; y:number}
class Point3D{x:number ; y:number ; z:number}
const p:Point = new Point3D()
//不会报错
接口兼容性
类和接口也是兼容的
interface Point {x:number ; y:number}
interface Point3D{x:number ; y:number}
class Point4D{
x:number
y:number
z:number
r:number
}
let p1: Point
let p2: Point2D = P1 //不会报错
interface Point3D{x:number ; y:number ; z:number}
let p3:Point3D
p2 = p3 //不会报错
p2 = new Point4D() //不会报错
函数兼容性
1.参数个数
参数少的可以赋值给参数多的
type f1 = (a:number)=>void
type f2 = (a:number, b:number)=>void
let F1:f1
let F2:f2 = F1
//forEach方法的第一个参数时回调函数,该类型为:
//(value:string,index:number,array:string[])=>void
const arr = ['a','b','c']
arr.forEach(()=>{})
arr.forEach((item)=>{})
2.参数类型
相同位置的参数类型要相同或兼容
//type为类型别名
type f1 = (a:number)=>void
type f2 = (a:string)=>void
let F1:f1
let F2:f2 = F1 //err:不能将number类型赋值string
interface Point2D{x:number ; y:number}
interface Point3D{x:number ; y:number ; z:number}
type F2 = (p:Point2D)=>void
type F3 = (p:Point3D)=>void
let f2:F2
let f3:F3 =f2
f3=f2 //不报错
f2=f3 //err:不兼容
注意:
1.这与前面的接口兼容性冲突
2.可以理解为接口使用type引用后每个属性变成了一个参数,因而参数少的可以赋值给参数多的
3.返回值类型
只关注返回值类型本身就可以
//返回值类型相同可以兼容
type F5 = ()=>string
type F6 = ()=>string
let f5:F5
let f6:F6 = f5
//返回值类型为对象时,遵循类的兼容条件
//即成员多的可以赋值给成员少的
type F7 =()=>{name:string}
type F8 =()=>{name:string; age:number}
let f7:F7
let f8:F8
f7=f8