在寫 TypeScript 時,有時候會有我們很清楚該值的型別,但 TypeScript 卻不知道的情形,例如 call API 拿回來的資料。
以下面的的例子來看:
const value: unknown = "this is a string";
console.log(value.length); // error
我們知道 value
是字串型別,不過在第二行卻噴錯了,因為 TS 不知道這是字串,除非你寫成 any
或是用下面的方法:
我們可以把 value
的值斷言為 string
型別,這樣就能用 ``.length` 取得長度了。
const value: unknown = "this is a string";
console.log((value as string).length);
注意上面的 (value as string)
,使用關鍵字 as
能將值斷言為其他類型。
另一種則是尖掛號寫法:
const value: unknown = "this is a string";
console.log((<string>value).length);
其中的 (<string>value)
也能將該值斷言為其他型別。
使用型別斷言需要注意自己做了什麼事,避免出現下面的情況:
interface person {
age: number;
name: string
}
const obj: person = {} as person
我宣告了一個 obj
型別是 person
,值是空陣列。不過後面斷言型別為 person
,所以程式碼沒有噴錯,只是會讓人覺得是不是忘記給值了?
接著來學習 TypeScript 中的問號 (?) 與驚嘆號 (!):
首先看一下 function
中參數裡的問號,這裡的問號代表可選參數:
function printName(name?: string){
console.log(name);
}
// 不帶參數也沒問題!
printName()
同樣的,使用 interface
或是 class
也能用問號代表可選屬性。
class Person {
name?: string
}
interface Animal {
name?: string
}
另外還有一個用法是 ?.
,用法與 && 相同。
const a = {
b: { c: 1 }
}
console.log(a?.b?.c);
// 等同於 a && a.b && a.b.c
!
的作用是:告訴 TS 這個值不是 null
或是 undefined
。
以下面的例子來看:
function fn1(num: number){
// ...
}
function fn2(num?: number){
fn1(num) // error
}
會出 error 的原因是,一旦用了 ?
可選參數,代表 num 有可能會是 number
或是 undefined
型別,這時候可以用 !
告訴 TS 這個 num 不會是空值。
function fn2(num?: number){
fn1(num!) // 加驚嘆號
}
這個問題也常會在我們抓 DOM 的時候看到:
const input = document.querySelector('input')
input.addEventListener('click', ()=>{
console.log('Hi')
})
這時候 TS 會警告我們:
可以選擇用 as
告訴 TS 型別,或是加 !
代表不是 null
。
// 使用 as
const input = document.querySelector('input') as HTMLInputElement
// 或是 !
const input = document.querySelector('input')!
除此之外,在繼承時也可以運用 !
:
interface A {
name?: string;
}
class B implements A {
name!: string;
}
A
的 name 有可能是 undefined
,當 B 繼承 A 時我們不希望 name 是 undefined
,所以在後面加個驚嘆號表示。
因此可以看到 B 的 name 一定是 string
型別: