型別斷言(Type Assertion)可以用來手動指定一個值的型別。
語法:
<型別>值
或
值 as 型別
tsx中只能使用後者
還記得聯合型別嗎?有時候我們在確定型別之前可能就需要使用某個特定型別的屬性,此時就可以用型別斷言來指定目標變數的型別。
function getLength(something: string | number): number { if (something.length) { return something.length; } else { return something.toString().length; } } // index.ts(2,19): error TS2339: Property 'length' does not exist on type 'string | number'. // Property 'length' does not exist on type 'number'. // index.ts(3,26): error TS2339: Property 'length' does not exist on type 'string | number'. // Property 'length' does not exist on type 'number'.
function getLength(something: string | number): number { if ((<string>something).length) { return (<string>something).length; } else { return something.toString().length; } }
不可以斷言不存在的型別
function toBoolean(something: string | number): boolean { return <boolean>something; } // index.ts(2,10): error TS2352: Type 'string | number' cannot be converted to type 'boolean'. // Type 'number' is not comparable to type 'boolean'.
as 的用法:
function toBoolean(something: any): boolean { return something as boolean; }
父子型別:
class ApiError extends Error { code: number = 0; } class HttpError extends Error { statusCode: number = 200; } function isApiError(error: Error) { if (typeof (error as ApiError).code === 'number') { return true; } return false; }
盡量不要使用 as any,但也不是說完全不能使用,要視情況決定
雙重斷言
interface Cat { run(): void; } interface Fish { swim(): void; } function testCat(cat: Cat) { return (cat as any as Fish); }
沒事不要使用雙重斷言
參考: https://ts.xcatliu.com/basics/type-assertion.html#类型断言-vs-类型转换