當函數總是拋出錯誤時,Typescript 的類型縮小不起作用
我有一個工具函數,我用它以有組織的方式拋出不同類型的錯誤。它總是會拋出錯誤。然而,Typescript 不夠智能,無法用它來進行類型縮小:
interface A {
x: {
a?: string;
}
}
const g = (s: A): string => {
if (!s.x.a) {
throw Error("mess");
}
return s.x.a // compiles just fine
}
const f = (): never => {
throw Error('message');
}
const gg = (s: A): string => {
if (!s.x.a) {
f()
}
return s.x.a // ERROR: can be undefined!
}
我以為回傳 never 會幫助編譯器變得更聰明,但並沒有。有沒有其他方法或關鍵字可以使用來達到這個目的?
答案#1
你不能真的讓 f 魔法般地將它被調用時的任何條件變成斷言條件,但如果你將該條件直接傳遞給 f 並使用 asserts,那麼你將會得到類似於 Node.js 內建 asserts 函數的東西:
function f(thing: any): asserts thing {
if (!thing) throw Error('message');
}
與真品相當神似:
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg);
}
}
遊樂場
答案#2
為什麼不直接返回 f,因為你知道它反正會拋出異常並停止執行
const gg = (s: A): string => {
if (!s.x.a) {
return f()
}
return s.x.a // ERROR: can be undefined!
}
