ts类型兼容

ts类型兼容

  1. 结构类型:结构类型是一种只用其成员来描述类型的方式,比如类,接口。兼容性规则:(1)如果 x 要兼容 y(即 x = y),那么y至少要具有x相同的属性;(2)或者说只能将 “子类” 赋值 给 “父类”,反过来不成立;检查函数参数的时候也是这种兼容性规则
1,可以使用第(1)中理解,y 中包含了 name 属性
interface Named {
    name: string;
}
let x: Named
let y = { name: 'Alice', location: 'Seattle' }
x = y

例2,可以使用第(1)中理解,y 中包含了 name 属性
function greet(n: Named) {
    console.log('Hello, ' + n.name)
}
greet(y)3 使用第一种理解:p2包含了name属性,p1也包含了name属性
	使用第二种理解:Mytype 和 Person 都只有一个name属性,所以可以看成 Person 继承了 MyType,又可以看成 Mytype 继承了 Person,所以 MyType 和 Person 都可以被看做成 "子类""父类",p1 = p2 时,Person 作为 "子类",p2 = p1 时,MyType 作为 "子类"
interface MyType {
  name: string
}
class Person {
  name: string = '123'
}
let p1: MyType
let p2: Person
p1 = p2 // ok
p2 = p1 // ok
  1. 函数:兼容性规则:
    (1) 参数:
    y = x 则 x 里面的每一个参数及其类型 都能在 y 里面找到对应的参数及其类型(参数名可以不同,看类型就行了,)
    并且顺序不能颠倒,在下面的例子中如果 换成 b:string, s:number 则报错,无法赋值
    (2) 返回值:
    源函数(赋值语句右边)的返回值类型必须是目标函数(赋值语句左边)返回值类型的子类型,{ name: ‘Alice’ } 可以看做成 { name: ‘Alice’, location: ‘Seattle’ } 的 “父类”
// 比较两个函数是否兼容
let x = (a: number) => 0
let y = (b: number, s: string) => 0
y = x // OK
// x = y // Error    y 函数的参数 s,x 函数不具备

let x1 = () => ({ name: 'Alice' })
let y1 = () => ({ name: 'Alice', location: 'Seattle' })

x1 = y1 // OK
// y1 = x1; // Error, because x() lacks a location property
  1. 枚举:枚举类型与枚举类型(不兼容),枚举类型与数字类型(兼容)
enum Color {
  red,
  green
}
enum Status {
  finished,
  error,
  success
}
let num: number
num = Color.red
console.log(num)
num = Status.finished
console.log(num)
let myname = Color.red
// myname = Status.success  // 不能将类型“Status.success”分配给类型“Color”。

  1. 类:比较两个类类型的对象时,只有实例的成员会被比较(比较的是类型和数量)。 静态成员和构造函数不在比较的范围内。类的私有成员和受保护成员会影响兼容性.
    兼容性规则:
    1. 源类型(赋值语句右边)必须包含目标类型(赋值语句左边)的成员
    2. 如果目标类型包含一个私有成员,那么源类型必须包含来自 同一个 类 的这个私有成员.(注意是来自同一个类,而不是两个类分别在类中分别定义了私有属性) 同样地,这条规则也适用于包含受保护成员实例的类型检查
    3. 允许子类赋值给父类
class Animal {
  feet: number
  // private mySelf: string
  constructor(name: string, numFeet: number) {}
}
class Size {
  // private mySelf: string
  feet: number
  num: number
  constructor(numFeet: number) {}
}
class Son extends Size {}
let a: Animal
let s: Size
let d: Son
a = s // OK
// s = a // error  不包含 num 成员
s = d // ok

如果将 Animal 类和Size类中的 定义私有成员的注释去掉,则 a = s
会报错,因为含有了不来自同一个类的私有成员,而 s = d 是正常的,因为 允许子类赋值给父类

  1. 泛型:看成员和类型,兼容性规则:没有成员的时候,与类型无关;含有成员的时候类型必须一致;没有指定类型的时候被当做 any 看待;
interface Empty<T> {
}
let x: Empty<number>
let y: Empty<string>
x = y // ok,虽然类型不同,但是Empty没有成员,所以在使用时并没有什么不同
interface NotEmpty<T> {
    data: T
}
let x: NotEmpty<number>
let y: NotEmpty<string>
x = y  //error 含有成员 data 类型不同会有影响
let identity = function<T>(x: T): T {
    // ...
}
let reverse = function<U>(y: U): U {
    // ...
}
identity = reverse  // OK, because (x: any) => any matches (y: any) => any
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值