TS 中的逆变和协变

97 阅读1分钟

协变逆变都是术语

协变

协变指的是能够使用比原来类型的派生程度更大(更具体的)的类型。

  • 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

总结

逆变协变 只是术语,根本目的是为了类型安全。具体看谁是给予者,谁是接收者,给予者一定是比接收者类型的派生程度更大(更具体的)的类型。