前言
类型断言可以用来指定一个值的类型,通过类型断言这种方式可以告诉编译器:"相信我,我知道我在干什么"。
语法
值 as 类型
或者
<类型>值
在tsx语法中必须使用前者,这里也建议使用前者。
简单使用的两种方式
两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
将一个联合类型断言为其中一个类型
当联合类型中的变量不确定是哪一个类型的时候,我们只能去访问此联合类型中共有的属性和方法.
interface Cut {
name: string,
age: number,
show(): void
}
interface Hit {
name: string,
age: number,
hide(): void
}
const tom: Cut | Hit = {
name: 'along',
age: 2,
show () {
return 'show';
},
hide () {
return 'hide';
}
}
function Fa(getName: Cut | Hit) {
return getName.name
}
Fa(tom); //along
但是当我们想调用show或者hide方法时,这时候会报错.大致意思就是show方法不是联合类型的共有属性,并在show不存在Hit上。那么我们想要单独访问,只能使用类型断言。
Property 'show' does not exist on type 'Cut | Hit'.
Property 'show' does not exist on type 'Hit'.
此时,在访问show时,将类型断言为Cut,这样就可以解决上面这个问题。
interface Cut {
name: string,
age: number,
show(): void
}
interface Hit {
name: string,
age: number,
hide(): void
}
const tom: Cut | Hit = {
name: 'along',
age: 2,
show () {
return 'show';
},
hide () {
return 'hide';
}
}
function Fa(getName: Cut | Hit) {
return (getName as Cut).show()
}
------------------------------------------------
function Fa(getName: Cut | Hit) {
return (<Cut>getName).show();//不推荐
}
Fa(tom); //show
需要注意的一个点就是类型断言是可以欺骗编译器,但也要注意写法,不可少写类型参数,否者运行的时候依然会报错,下面这段代码,这写完的时候,编译器是没有给我们报错的,但是运行的时候是有报错的。
interface Cut {
name: string,
age: number,
show(): void
}
interface Hit {
name: string,
age: number,
hide(): void
}
const tom: Cut | Hit = {
name: 'along',
age: 2,
hide () {
return 'hide';
}
}
function Fa(getName: Cut | Hit) {
return (getName as Cut).show()
}
Fa(tom)
//getName.show is not a function
可以看到,show方法不存在tom对象中,但是由于联合类型的写法,让我们欺骗了编译器,从而没有报错.
将任何一个类型断言为any
可以看下面一个例子,我们想要在window上访问一个变量,看起来一点问题都没有.
在javscript中可以看到,这是没有问题的
在ts中我们可以看到,是有报错的.提示window上不存在foo属性.
window.foo = 1;
//Property 'foo' does not exist on type 'Window & typeof globalThis'.
此时我们window断言为任意类型,这时候就可以正常定义。因为在any类型的变量上,访问任意属性都是可以的.
(window as any).foo = 1;
注意:它极有可能掩盖真正的类型错误,如果不是非常确定,我们不要去使用它,当然也不能否定它的作用,我们需要在类型的严格性和开发的便利性掌握平衡.
将any断言为一个具体的类型
看下面这样一个例子。一个函数返回值是any,我们需要将它的返回值类型断言为一个精确的类型,这时候我们可以这样做:
function fa(a: string): any {
return Number(a);
}
interface Cut {
name: string,
show(): void
}
let b = fa('2') as Cut;
这样,就可以将b断言为Cut类型,在对b操作的时候,就有了代码补全