TS的接口和类型兼容性

76 阅读2分钟

接口

接口用于约束对象,类,函数的契约

  • 接口约束对象
interface User{
    name: string
    age: number
}

let u:User = {
    name: 'zero',
    age: 18
}
  • 约束函数
// 案列一
interface User{
    sayHello: () => void  // 或者sayHello(): void
} 

let u: User = {
    sayHello() {
        console.log('hello')
    }
}

// 案例二
// 类型别名
// type Condition = (n: number) => boolean

// 接口
interface Condition{
  (n: number): boolean
}

function sum(numbers: number[], callBack: Condition) {
let s = 0
numbers.forEach(n => {
  if(callBack(n)) {
    s += n
  }
})
return s
}

const result = sum([1,2,3,4,5], n=>n % 2 !==0)
console.log(result)  // 9
  • 接口可以继承 可以通过接口之间的继承,实现多种接口之间的组合;子接口不能覆盖父接口的成员
interface A{
    T1: string
}

interface B extends A{
    T2: number
}

// u变量必须包含A和B的属性
let u:B = {
    T2: 33,
    T1: 'zero'
}

readonly

  • 只读修饰符,修饰的目标是只读的,不在编译结果中
 interface User{
     readonly id: string
     name: string
 }
 
 // 只读修饰符只能首次赋值
 let u: User = {
     id: '123',
     name: 'zero'
 }
 
 // 修饰数组只读的类型
 const arr: readonly number[] = [3,4,6]
 const arr: ReadonlyArray<number> = [3,4,6]

类型兼容性

B->A,如果能完成赋值,则B和A类型兼容

  • 基本类型: 完全匹配
  • 对象类型: 鸭子辨型法
  • 函数类型: 通常出现在回调

当直接使用对象字面量赋值的时候,会进行更加严格的判断

鸭子辨型法(子结构辨型法)

目标类型需要某一些特征,赋值的类型只要能满足该特征即可

interface Duck{
    sound: "嘎嘎嘎"
    swin(): void
}

let person = {
    name: "伪装成鸭子的人",
    age: 18,
    sound: '嘎嘎嘎' as '嘎嘎嘎'//类型断言,前面是数据,后面是断言
    swin() {
        console.log(this.name + "正在游泳,并发出来"+this.sound +"的声音 ")
    }
}

// 人的某些特征满足鸭子的属性,可以赋值
let duck:Duck = person

// 对象字面量直接赋值
let duck1: Duck = {
    sound: '嘎嘎嘎' as '嘎嘎嘎'//类型断言,前面是数据,后面是断言
    swin() {
        console.log("正在游泳,并发出来"+this.sound +"的声音 ")
}