let obj: { toString(): string } let a = '123' obj = a
2.类的兼容性
父类的变量能够指向子类的实例,子类的变量不能指向父类的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// ? 类的兼容性 class Animal { constructor(public name: string){} } class Bird extends Animal { constructor(name: string, public swing: string){ super(name) } } let c: Animal; c = new Bird('this is a bird', 'i can swing') // * 可以,因为 c 拥有 name 属性即可 let d: Bird; // d = new Animal('animal'); // ! 不行,因为 d 上缺少 swing 属性 d = {name: 'x', swing: 'y'}; // 可以
3.函数的兼容性
函数的参数少可以,不能多
函数的返回值指定函数返回数据的结构,多可以,不能少
4.函数参数的协变
函数的某个参数类型,多可以,不能少
虽然可以将log1赋值给log ,但log的类型还是没有发生变化
5.枚举的兼容性
二、类型保护
通过if判断,或者!.非空断言(如s!.toString())更精确地知道变量属于哪种类型
通过if判断在联合类型中锁定类型
自定义的类型保护
联合类型和交叉类型
一、交叉类型
交叉类型定义的变量必须实现所有属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
namespace d { interface Bird{ name: string; fly(): void } interface Pig { name: string; eat(): void } // * 使用 type 定义交叉类型 type Animal = Bird & Pig let a: Animal = { name: '小猪佩奇', fly(){}, eat(){} } }
namespace d { interface Bird{ name: string; fly(): void } interface Pig { name: string; eat(): void } // * 使用 type 定义交叉类型 type Animal = Bird & Pig let a: Animal = { name: '小猪佩奇', fly(){}, eat(){} } }
namespace e { // * 使用 typeof 提取某一个变量的类型 let p = { name: 'lihua', age: 13 } type Person = typeof p // ! 注意:定义类型只能用 type 不可以使用 let let p2: Person = { name: 'hanmeimei', age: 20 } }