ts笔记-类型断言

TypeScript 允许你覆盖它的推断,并且能以你任何你想要的方式分析它,这种机制被称为「类型断言」。类型断言使用as关键字或者<type>表示。

const foo = {};
foo.bar = 123; // Error: 'bar' 属性不存在于 ‘{}’
foo.bas = 'hello'; // Error: 'bas' 属性不存在于 '{}'

由于对象foo不存在任何属性,因此给属性赋值就报错了,可以通过类型断言避免此问题。

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

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';

// 另一种形式(由于这种形式和jsx容易混淆,建议使用as关键字)
const bar = <Foo>{};

类型断言应该少用

使用类型断言,如果我们没有按接口约定添加属性,ts不会发出错误警告。

interface Foo {
  bar: number;
  bas: string;
}
// 没有为foo添加bar和bas属性,也没有错误警告
const foo = {} as Foo


// 没有为bar添加bar和bas属性,也没有错误警告
const bar = <Foo>{}

为了避免出现上面的问题,建议使用ts自身提供的类型推断,减少使用类型断言。

const foo: Foo = {

}

使用示例

function handler(event: Event) {
  // 可以使用MouseEvent的属性和方法
  const mouseEvent = event as MouseEvent;
}

说明:MouseEvent 派生自 UIEvent,UIEvent 派生自 Event,因此MouseEvent继承了UIEvent和Event的属性和方法。但不能把event断言成HTMLElement,因为Event和HTMLElement没有任何关系。

function handler(event: Event) {
  const element = event as HTMLElement; // Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个
}

如果非要断言成HTMLElement也是有办法的,使用双重断言。首先断言成兼容所有类型的 any,再断言成HTMLElement。

function handler(event: Event) {
  const element = (event as any) as HTMLElement; // ok
}

判断是否能够断言

当 S 类型是 T 类型的子集,或者 T 类型是 S 类型的子集时,S 能被成功断言成 T,当然T 能被成功断言成 S。这是为了在进行类型断言时提供额外的安全性,完全毫无根据的断言是危险的,如果你想这么做,你可以使用 any

关于继承和派生

假设有基类A,子类B、派生类C,那么B类继承了A的属性和方法,同时可以定义自己的属性和方法。C类是派生类,他实现了A的接口,同时也可以定于你自己的属性和方法。

posted @ 2021-10-19 19:33  wmui  阅读(905)  评论(0编辑  收藏  举报