# 八.类型的兼容性

前言

TS 中的兼容性,主要看结构是否兼容(核心是考虑安全性)

# 1.基本数据类型的兼容性

let temp: string | number
let num!: number
temp = num
1
2
3
let num: {
  toString(): string
}
let str: string = "ab"
num = str // 字符串中具备toString()方法,所以可以进行兼容
1
2
3
4
5

# 2.接口兼容性

interface IAnimal {
  name: string
  age: number
}
interface IPerson {
  name: string
  age: number
  address: string
}
let animal: IAnimal
let person: IPerson = {
  name: "ab",
  age: 11,
  address: "ddddd",
}
animal = preson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

接口的兼容性,只要满足接口中所需要的类型即可

# 3.函数的兼容性

函数的兼容性主要是比较参数和返回值

  • 参数
let sum1 = (a: string, b: string) => a + b
let sum2 = (a: string) => a
sum1 = sum2
1
2
3

赋值函数的参数要少于等于被赋值的函数,与对象相反,例如

type Func<T> = (item: T, index: number) => void
function forEach<T>(arr: T[], cb: Func<T>) {
  for (let i = 0; i < arr.length; i++) {
    cb(arr[i], i)
  }
}
forEach([1, 2, 3], (item) => {
  console.log(item)
})
1
2
3
4
5
6
7
8
9
  • 返回值
type sum1 = () => string | number
type sum2 = () => string
let fn1: sum1
let fn2!: sum2
fn1 = fn2
1
2
3
4
5

# 4.函数的逆变与协变

函数的参数是逆变的,返回值是协变的(在非严格模式下函数的参数是双向协变的)

class Parent {
  address: string = "eeeee"
}
class Child extends Parent {
  money: number = 100
}
class Grandsom extends Child {
  name: string = "abc"
}
type Callback = (person: Child) => Child
function execCallback(cb: Callback) {}
let fn = (person: Parent) => new Grandsom()
execCallback(fn)
1
2
3
4
5
6
7
8
9
10
11
12
13

通过这个案例可以说明,函数参数可以接收父类,返回值可以返回子类

# 5.类的兼容性

class Perent {
  name: string = "abc"
  age: number = 11
}
class Parent1 {
  name: string = "abc"
  age: number = 11
}
let parent: Perent = new Parent1()
1
2
3
4
5
6
7
8
9

这里要注意的是,只要有 private 或者 protected 关键字类型就会不一致,但是继承的类可以兼容

class Parent1 {
  protected name: string = "abc"
  age: number = 11
}
class Child extends Parent1 {}
let child: Parent1 = new Child()
1
2
3
4
5
6

# 6.泛型的兼容性

interface IT<T> {}
let obj1: IT<string>
let obj2: IT<number>
obj1 = obj2
1
2
3
4

# 7.枚举的兼容性

enum USER1 {
  role = 1,
}
enum USER2 {
  role = 1,
}
let user1!: USER1
let user2!: USER2
user1 = user2 //错误语法
1
2
3
4
5
6
7
8
9

不同的枚举类型不兼容