TypeScript 認為錯誤unknown
是公平的,但會導致我撰寫我認為丑陋的代碼。例如,要處理我知道有一個"code"
屬性的特定錯誤(但我不知道類所以不能使用instanceOf
),我必須這樣寫:
} catch (err) {
if (
typeof err === "object" &&
err !== null &&
"code" in err &&
(err as { code: unknown }).code === "<some value>"
) {
console.log("Special case for this particular situation")
}
throw err;
}
我覺得這個丑陋的,太多的代碼,我仍然需要做一個演員。現在很想err
改用any
,但我想做正確的 TypeScript。
有什么更好的方法來做到這一點?
uj5u.com熱心網友回復:
我通常會做Clashsoft 展示的內容。只需鍵入err
asany
然后有幾個警衛。
但是,如果您在很多地方都這樣做,那么擁有一個可以重用的型別謂詞可能會很有用:
function isErrorWithCode(err: any): err is { code: string; } {
return err && typeof err === "object" && "code" in err && typeof err.code === "string";
}
那么用法是:
try {
// ...
} catch (err) {
if (isErrorWithCode(err) && err.code === "<some value>") {
console.log("Special case for this particular situation")
}
throw err;
}
如果你真的想讓它更方便,你可以將型別謂詞與一個檢查給定錯誤代碼的函式結合起來:
function errorHasCode(err: any, code: string) {
return isErrorWithCode(err) && err.code === code;
}
然后:
try {
// ...
} catch (err) {
if (errorHasCode(err, "<some value>")) {
console.log("Special case for this particular situation")
}
throw err;
}
為了方便起見,我在我的 Excel JavaScript 加載項代碼庫中有它。(Excel JavaScript API 有時會拋出帶有code
字串屬性的錯誤。)
uj5u.com熱心網友回復:
如果你只需要code
,我會選擇這個:
} catch (err: any) {
if (err?.code === 'whatever') {
console.log("Special case for this particular situation")
}
throw err;
}
如果err
是null
,則可選鏈運算式將產生undefined
,這可能不是您的whatever
. 如果err
沒有code
屬性,結果相同。
uj5u.com熱心網友回復:
你可以在一個類中轉換你的錯誤,拋出它,然后檢查錯誤instanceof
try {
throw new MyError({ code: "Hello, world" });
} catch (e) {
if (e instanceof MyError) {
console.log(e.code);
}
}
否則,您可以使用一些像Zod這樣的庫來驗證它,但僅僅為此引入 Zod 可能有點矯枉過正。
uj5u.com熱心網友回復:
不是兩種情況:
提前知道錯誤的型別(在這種情況下,您可以安全地構造一個介面/型別來反映這一點,如果一個不可用,并進行型別
as
轉換以保證塊內未來的型別安全)你不知道型別,但你知道你感興趣的屬性,在這種情況下,像你這樣的解決方案是必要的,因為你試圖從任何可能的型別(例如
any
/unknown
)到特定的TS 編譯器將理解并能夠在塊內遵守的子型別
一個中途的解決方案可能是用你知道的資訊定義一個型別并省略其余的,例如
interface SpecificError {
code: string,
// ...
}
} catch (err) {
const eTyped: SpecificError = e as SpecificError
eTyped.code // valid
}
或者
} catch (err) {
const eTyped: { code: string } = e as { code: string }
eTyped.code // valid
}
鑒于缺乏可用于實施選項 1 的資訊,實施選項 2 的方法略短。
編輯:@tj-crowder 使用型別保護的解決方案也是實作相同想法的一種優雅方式。如果“快速但骯臟”的方法也很有價值,請留下這個答案
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/527575.html
標籤:打字稿