TypeScript
结构化类型系统的基本规则是,如果x
要兼容y
,那么y
至少具有与x
相同的属性。比如:
interface Named {
name: string
}
let x: Named
let y = { name: "zhangsan", age: 12 }
x = y; //OK
x
的每个参数在 y
中都能找到对应的参数,所以可以把y
赋值给x
。但如果反过来,y
并没有兼容 x
,因为 y
的属性比 x
多了一个。
函数类型的兼容性
x
是否能赋值给y
,首先要看它们的参数列表。x
的每个参数如果能在y
里找到对应类型的参数,就可以赋值。 注意参数的名字相同与否无所谓,只看它们的类型。
let x = (a: string) => a;
let y = (a: string, b: number) => a;
x = y; //Error
y = x; //OK
如果函数中出现了可选参数,如果你在tsconfig.json
默认配置下兼容性是没问题的,但是当我们设置了strictNullChecks
为true
:
let x = (a?: string) => a;
let y = (a: string, b: number) => a;
x = y; //Error
y = x; //Error
因为可选类型的参数有可能是
undefined
,在这种情况下不能兼容。
枚举
枚举类型与数字类型兼容,并且数字类型与枚举类型兼容。不同枚举类型之间是不兼容的:
enum Color1 {
Red,
Green,
Blue
}
enum Color2{
Black,
White
}
let num: number = Color1.Red;//OK
let enum1: Color1 = 10;//OK
类
比较两个类类型的对象时,只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内:
class Animal{
feet: number;
constructor(name: string, numFeet: number) {
this.feet = numFeet;
}
}
class Size {
feet: number;
constructor(meters: number) {
this.feet = meters
}
}
let a: Animal = new Animal("name1",4);
let s: Size = new Size(8);
a = s; //OK
s = a; //OK
类的私有成员和受保护成员:
class Animal {
protected name: string
}
class Dog extends Animal{}
let animal: Animal ;
let dog: Dog;
animal = dog; //OK
dog = animal; //OK
class Person {
protected name:string
}
let p: Person;
animal = p;//Error 属性“name”受保护,但类型“Person”并不是从“Animal”派生的类