TypeScript 類型斷言
本節(jié)介紹類型斷言,有使用關鍵字 as
和標簽 <>
兩種方式,因后者會與JSX
語法沖突,建議統(tǒng)一使用 as
來進行類型斷言。
1. 慕課解釋
TypeScript 允許你覆蓋它的推斷,畢竟作為開發(fā)者你比編譯器更了解你寫的代碼。
類型斷言主要用于當 TypeScript 推斷出來類型并不滿足你的需求,你需要手動指定一個類型。
2. 關鍵字 as
當你把 JavaScript 代碼遷移到 TypeScript 時,一個常見的問題:
const user = {}
user.nickname = 'Evan' // Error, Property 'nickname' does not exist on type '{}'
user.admin = true // Error, Property 'admin' does not exist on type '{}'
代碼解釋: 編譯器推斷 const user: {}
,這是一個沒有屬性的對象,所以你不能對其添加屬性。
此時可以使用類型斷言(as關鍵字)覆蓋其類型推斷:
interface User {
nickname: string,
admin: boolean,
groups: number[]
}
const user = {} as User
user.nickname = 'Evan'
user.admin = true
user.groups = [2, 6]
代碼解釋:
第 7 行,這里通過 as
關鍵字進行類型斷言,將變量 user
的類型覆蓋為 User
類型。但是請注意,類型斷言不要濫用,除非你完全明白你在干什么。
3. 首尾標簽
類型斷言還可以通過標簽 <>
來實現(xiàn):
interface User {
nickname: string,
admin: boolean,
groups: number[]
}
const user = <User>{} // User類型
user.nickname = 'Evan'
user.admin = true
user.groups = [2, 6]
代碼解釋:
第 7 行,使用 <User>{}
這種標簽形式,將變量 user 強制斷言為 User 類型。
但是,當你在使用 JSX
語法時,會跟標簽 <>
形式的類型斷言混淆:
let nickname = <User>Evan</User> // 這里的 User 指向一個 component
所以,建議統(tǒng)一使用 as type
這種語法來為類型斷言。
4. 非空斷言 !
如果編譯器不能夠去除 null 或 undefined,可以使用非空斷言 !
手動去除。
function fixed(name: string | null): string {
function postfix(epithet: string) {
return name!.charAt(0) + '. the ' + epithet; // name 被斷言為非空
}
name = name || "Bob"
return postfix("great")
}
代碼解釋:
第 2 行,postfix()
是一個嵌套函數(shù),因為編譯器無法去除嵌套函數(shù)的 null (除非是立即調用的函數(shù)表達式),所以 TypeScript 推斷第 3 行的 name
可能為空。
第 5 行,而 name = name || "Bob"
這行代碼已經(jīng)明確了 name
不為空,所以可以直接給 name 斷言為非空(第 3 行)。
5. 雙重斷言
雙重斷言極少有應用場景,只需要知道有這種操作即可:
interface User {
nickname: string,
admin: boolean,
group: number[]
}
const user = 'Evan' as any as User
代碼解釋: 最后一行,使用 as 關鍵字進行了兩次斷言,最終變量 user 被強制轉化為 User 類型。
6. 小結
本節(jié)介紹了幾種類型斷言的方法,需要注意:
- 慎用類型斷言,除非你真的有把握。
- 類型斷言是一個編譯時語法,不涉及運行時。