协变和逆变都是术语
协变
协变指的是能够使用比原来类型的派生程度更大(更具体的)的类型。
- example 1
let a: string | number = 1
let b: string = a // wrong
let c: number = 2
a = c // ok
- example 2
interface Fans {
call: any
}
interface IKun extends Fans {
sing: any
dance: any
basketball: any
}
interface SuperIKun extends IKun {
rap: any
}
let fans: Fans = {
call: ''
}
let ikun: IKun = fans // error
console.log(ikun.basketball) // error
let ikun: IKun = {
call: '',
sing: '',
dance: '',
basketball: ''
}
let fans: Fans = ikun
console.log(fans.call) // ok
逆变
逆变指的是能够使用比原来类型的派生程度更小(不太具体的)的类型。
- example
type Transform = (x: IKun) => Ikun
type SubTransform = (x: SuperIKun) => SuperIKun
const subtransform: SubTransform = (x) => {
console.log(x.rap)
return x as any
}
const transform: Transform = subtransform // wrong
transform(ikun) // wrong
const transform: Transform = (x) => {
console.log(x.basketball)
return x as any
}
const subtransform: SubTransform = transform // ok
let superIkun: SuperIKun = Object.assign(ikun, {
rap: ''
})
subtransform(superIkun) // ok
总结
逆变和协变只是术语,根本目的是为了类型安全。具体看谁是给予者,谁是接收者,给予者一定是比接收者类型的派生程度更大(更具体的)的类型。