断言
把两种能有重叠关系的数据类型进行相互转换的一种 TS 语法,把其中的一种数据类型转换成另外一种数据类型。类型断言和类型转换产生的效果一样,但语法格式不同。类型断言语法格式为 “A 数据类型的变量 as B 数据类型”(A 数据类型和 B 数据类型必须具有重叠关系)。以下几种场景都属于重叠关系;1)如果 A,B 是类,并且有继承关系; -【 extends 关系】无论 A,B 谁是父类或子类, A 的对象变量可以断言成 B 类型,B 的对象变量可以断言成A类型 。但大多数场景下都是把父类的对象变量断言成子类。 2)A,B 如果是类,但没有继承关系; - 两个类中的任意一个类的所有的 public 实例属性【不包括静态属性】加上所有的 public 实例方法和另一个类的所有 public 实例属性加上所有的 public 实例方法完全相同或是另外一个类的子集,则这两个类可以相互断言,否则这两个类就不能相互断言。 3)如果 A 是类,B 是接口,并且 A 类实现了 B 接口【implements】 ; - A 的对象变量可以断言成 B 接口类型,同样 B 接口类型的对象变量也可以断言成A类型,类似第一项。
4)如果 A 是类,B 是接口,并且 A 类没有实现了 B 接口; - 则断言规则和第三项相同。 5)如果 A 是类,B 是 type 定义的数据类型; - 【就是引用数据类型,例如 Array, 对象,不能是基本数据类型,例如 string,number,boolean】,如果有 A 类实现了 B type 定义的数据类型【 implements】,则 A 的对象变量可以断言成 B type 定义的对象数据类型,同样 B type 定义的对象数据类型的对象变量也可以断言成 A 类型 。 6)如果 A 是类,B 是 type 定义的数据类型,并且 A 类没有实现 B type定义的数据类型; - 则断言规则和第二项相同。 7)如果 A 是一个函数上参数变量的联合类型; - string |number,那么在函数内部可以断言成 string 或number 类型。
8)多个类组成的联合类型如何断言? - 例如:let vechile: Car | Bus | Trunck。 vechile 可以断言成其中任意一种数据类型。 例如 vechile as Car, vechile as Bus , vechile as Trunck 。 9)任何数据类型都可以转换成 any 或 unknown 类型; - any 或 unknown 类型也可以转换成任何其他数据类型。
A,B 是类,并且有继承关系 & 没有继承关系
// -----------------------> A,B是类,有继承关系 class People { public username!: string; public age!: number; constructor() {} step() {} } class Stu extends People { public username!: string public age!: number; public address!: string constructor(username: string, age: number, address: string) { super(); this.address = address; } study() {} } let people = new People(); people.study() // 报错,找不到study // 绝大多数是父类断言成子类 let result = people as Stu;// 类型断言 正确(父类断言成子类) result.study(); // 正确,Stu类上有study方法 // 子类断言成子类父类 let stu = new Stu("wangwu", 23, "北京"); let result2 = stu as People; // 正确 result2.study() // 报错(类型“People”上不存在属性“study”) // 如果是类型转换 let result = <Stu>people; // 类型转换 正确 result.study(); // -----------------------> A,B是类,没有继承关系,但是有一方的public属性覆盖另一方的 class People { constructor( public username: string, public age: number, ) {} } class Stu { public username!: string; public age!: number; public address!: string; constructor(username: string, age: number, address: string) { super(); this.address = address; } public study() {} } let people = new People("wangwu", 23); let stuedConvert = people as Stu; // 没有报错,Stu包含了People的所有public属性,所以People的属性是Stu的子集 let stu = new Stu("wangwu", 23, "北京"); let peopledConvert = stu as People; // 正确 People是Stu的子集
两个没有继承关系的类,只要其中一方所有的 public 实例属性【不包括静态属性】加上所有的 public 实例方法涵盖了另一个类的所有 public 实例属性加上所有的 public 实例方法,或是相同,则这两个类可以相互断言,否则这两个类就不能相互断言。
A 是类,B 是接口, A 类实现了 B 接口【implements】& 没有实现了 B 接口
interface People { username: string; age: number; address: string; } // Stu 实现了People接口 class Stu implements People { public username!: string; public age!: number; public address!: string; } // people对象实现了People接口 let people: People = { username: "wangwu", age: 23, address: "11", }; let result = people as Stu; // 正确,people可以断言成Stu,Stu类实现看People接口 let stu = new Stu("wangwu", 23, "北京"); stu as People; // 正确, // -----------------------> A是类,B是接口,没有继承关系,但是如果一方可以覆盖另外一方就可以断言,类似第二点 class Test { public username!: string; public age!: number; public address!: string; public phone!: string; public sex!: number; public old!: number; constructor(username: string, age: number, address: string) { this.address = address; } } let result = people as Test; //正确 let test = new Test("wangwu", 23, "北京"); test as People; // 正确,属性完全相同或者一方覆盖另外一方
A 是类,B 是 type 定义的数据类型并实现B type 数据类型 & 没有实现 B type定义的数据类型
和上述两个案例一样,如果A类实现了B type,那么可以相互断言,如果没有实现,并且一方的属性是另外一方的子集或者相同,同样可以断言
标签:断言,People,数据类型,Stu,类型,public,string From: https://www.cnblogs.com/goather/p/17381575.html