1. 程式人生 > 其它 >ts筆記-型別斷言

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的介面,同時也可以定於你自己的屬性和方法。

常用網站: SegmentFault | GitHub | 掘金社群