什么是类型断言?
就是可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型
语法格式
(1)<类型>值
(2)值 as 类型
有人说,类型断言更像是类型的选择,而不是类型的转换
案例一
// 这里,参数是联合类型,可以有两种类型,但是,ts编译的时候,val.length就会报错,因为假定参数是number,此时就不成立,因为后面代码编译时也不确定这个参数是什么类型。
function func(val:string|number):number{
if(val.length){
return val.length
}else{
return val.toString().length
}
}
// 所以,为了解决这种问题 ,ts里就有了类型断言
// 有个说法,<值 as 类型>
方式一: <值 as 类型> 会更好,在jsx 语法中 ,只支持这种写法
function func(val:string|number):number{
if(val as string).length){
return (val as string).length
}else{
return val.toString().length
}
}
方式二 : <类型>值
function func(val:string|number):number{
if((<stringval>).length){
return (<string>val).length
}else{
return val.toString().length
}
}
类型断言的限制(特点)
1、联合类型可以被断言为其中一个类型
2、父类可以被断言为子类
3、任何类型都可以被断言为any
4、any 可以被断言为任何类型
但,类型之间的断言确是有限制的。若类型A能兼容 ,类型B ,也可以将B断言为A
TS是结构类型系统,类型之间的对比只会比较它们最终的结构,而会忽略它们定义时的关系
// 尽管`Animal`、`Cat`定义时并没有任何关系,但结构上可以理解为`Cat`继承于`Animal`,此时二者可以互相断言
// (1)允许 `animal as cat` 是因为父类可以被断言为子类。 (2)允许 `cat as animal` 是因为子类拥有父类的所有属性和方法,调用也不会出问题
interface Animal{
name:string;
}
interface Cat{
name:string;
run():void;
}
const tom:Cat={
name:"tom",
run(){
console.log("running")
}
}
const animal:Animal=tom
个人觉得,断言的目标类型,应该是包含当前类型
最后,类型断言只会影响TS编译时的类型,类型断言语句会在编译结果中删除断言其实更像是对编译器的欺骗,是为了让编译通过,不代表运行时不报错,所以,对值各种可能的类型的还是要有相应的处理逻辑。在实际项目中,对于类型的断言也会变得更为复杂。