TypeScript:类型断言as

提出问题

TypeScript 会进行类型推断,但有时不是开发者想要的

例子

下面代码发出了错误警告,因为 foo 的类型推断为 {},即没有属性的对象。因此,你不能在它的属性上添加 bar 或 bas

const student = {};
student.name = '李雷'; // Error: 'name' 属性不存在于 {}
student.age = 20; // Error: 'age' 属性不存在于 {}

如下图;

解决

使用类型断言

类型断言

类型断言可以覆盖推断,并且能以想要的方式分析它

as方式断言

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo; // 类型断言
foo.bar = 123;
foo.bas = 'hello';

<类型>方式断言

最开始断言的实现方式,现在与 JSX 的语法存在歧义,不要使用

let foo: any;
let bar = <string>foo; // 现在 bar 的类型是 'string'

案例

定义 错误类,当程序报错时,将错误信息封装到 错误类中,在 catch(error) 中捕获错误,此时就需要用到 类型断言

/**
 * 定义错误类
 */
class AppError {
    code: number
    message:string
    constructor(code:number,message:string){
        this.code = code
        this.message = message
    }

}

定义除法函数,当除数是 0 就抛错:

function sub(a:number,b:number){

    if(b==0){
        throw new AppError(100,"除数不能是0")
    }
    return a/b
}

测试:

try{
    console.log("结果:",sub(5,0))
}catch(error){
    // 此处用到断言,将 error 转成 AppError,然后才能访问属性
    const err = error as AppError
    console.error(`错误码:${err.code},说明:${err.message}`)
}

执行结果:

错误码:100,说明:除数不能是0

类型断言是有害的

在很多情景下,断言能让你更容易的从遗留项目中迁移(甚至将其他代码粘贴复制到你的项目中)

应该小心谨慎的使用断言,下面代码中,使用类型断言后,没有指定属性的值:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo; // 使用类型断言后,下面没有指定属性的值

参考:
https://jkchao.github.io/typescript-book-chinese/typings/typeAssertion.html#%E5%8F%8C%E9%87%8D%E6%96%AD%E8%A8%80