04-TypeScirpt-类型推论和兼容性

2020-10-01  本文已影响0人  低头看云

类型推论

  // 如果是先定义初始化, 那么无法自动推断类型
  let value
  value = 123
  value = '123'

  console.log('value', value)

  // 如果是定义的同时初始化, 那么ts就会自动进行类型推荐
  let value1 = 123   // numer类型
  // value1 = "112" 保存

兼容性

类型兼容性

 interface TestInterface {
    name: string
  }

  let p1 = { name: 'lnj' }
  let p2 = { age: 18 }
  let p3 = { name: 'lnj', age: 18 }

  let t: TestInterface
  t = p1
  // t = p2   // 少了接口中的name 属性
  t = p3 // 可多不可少

  interface TestInterface1 {
    name: string
    children: {
      age: number
    }
  }

  let p11 = { name: 'lnj', children: { age: 18 } }
  let p22 = { name: 'lnj', children: { age: 'abc' } }

  // 类型不兼容
  let t1: TestInterface1
  t1 = p11
  // t1 = p22 // 会递归检查

函数兼容性

  // 参数个数
  let fn1 = (x: number, y: number) => {}

  let fn2 = (x: number) => {}
  fn1 = fn2
  // fn2 = fn1 // 参数可以少, 但是不可以多

  // 参数类型
  let argTypeFn1 = (x: number) => {}

  let argTypeFn2 = (x: number) => {}

  let argTypeFn3 = (x: string) => {}

  argTypeFn1 = argTypeFn2
  // argTypeFn1 = argTypeFn3 // 参数类型不一样
  // argTypeFn3 = argTypeFn1
  let returnFn1 = (): number => 123
  let returnFn2 = (): number => 456
  let returnFn3 = (): string => '123'

  returnFn1 = returnFn2
  // returnFn3 = returnFn1   // 返回值类型不一样
  // returnFn1 = returnFn3 // 返回值类型不一样
 // 返回值双向协变
  let fn11 = (x: boolean): number | string => (x ? 123 : 'abc')
  let fn22 = (x: boolean): number => 456
  // fn1 = fn2; // 但是可以将返回值是具体类型的赋值给联合类型的
  //   fn22 = fn11 // 不能将返回值是联合类型的赋值给具体类型的
  // 函数的重载
  function add(x: number, y: number): number
  function add(x: string, y: string): string

  function add(x: any, y: any) {
    return x + y
  }

  function sub(x: number, y: number): number

  function sub(x: any, y: any) {
    return x - y
  }

  // 可以将重载多的赋值重载少的, 反之,则不可以
  let fnc = sub
  fnc = add

类兼容性

 // 只比较实例成员, 不比较类的构造函数和静态成员
  class Person {
    public name: string
    public static age: number

    constructor(name: string, age: number) {
      this.name = name
    }
  }

  class Animal {
    public name: string
    constructor(name: string) {
      this.name = name
    }
  }

  let p: Person
  let a: Animal

  //   p = a
  //   a = p // 可以多但是不可以少
// 类的私有属性和受保护属性会影响兼容性
  class Person1 {
    protected name: string
    constructor(name: string) {
      this.name = name
    }
  }

  class Animal1 {
    private name: string
    constructor(name: string) {
      this.name = name
    }
  }

  let p1: Person1
  let a1: Animal1
  //   p1 = a1  // 报错

枚举兼容性

// 数字枚举与数值兼容
  enum Gender {
    Male,
    Female,
  }

  let value: Gender
  value = Gender.Male
  value = 1
// 数字枚举与数组枚举不兼容
  enum Gender1 {
    Male,
    Female,
  }

  enum Animal {
    DOg,
    Cat,
  }

  let value1: Gender
  value1 = Gender.Male
  // value1 = Animal.Cat // 报错
  // 字符串枚举与字符串不兼容
  enum Gender2 {
    Male = 'abc',
    Female = 'def',
  }
  let value2: Gender
  value = Gender.Male
  // value = 'abc' //Type '"abc"' is not assignable to type 'Gender'.

泛型兼容性

  interface TestInterface<T> {
    // 泛型只影响使用部分, 不会影响声明的部分
    num: T
  }

  let t1: TestInterface<number>
  let t2: TestInterface<string>

  // t1 = t2 //   Type 'string' is not assignable to type 'number'.
}
上一篇 下一篇

猜你喜欢

热点阅读