網站搜尋

當函數總是拋出錯誤時,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!
}