簡體   English   中英

當我在 TypeScript 中將它們與 ReturnType 一起使用時,類型保護不起作用

[英]Type guards doesn't work when I use them with ReturnType in TypeScript

我有和 enum 和兩個返回不同數據類型的函數:

enum Figure {
  Circle,
  Square,
}

const getCircle = () => ({
  figure: Figure.Circle,
  radius: 1
})

const getSquare = () => ({
  figure: Figure.Square,
  width: 1
})

我想要一個聯合類型AnyFigure以便我可以組合使用圓形和正方形。 我可以通過定義這兩種類型來做到這一點:

type CircleType = {
  figure: Figure.Circle,
  radius: number
}

type SquareType = {
  figure: Figure.Square,
  width: number
}

type AnyFigure = CircleType | SquareType

// this throws compiler error because circles doesn't have width, which is great
const figure: AnyFigure = { figure: Figure.Circle, width: 4 }

這很好用,但我不想定義每個“get figure” function 的返回類型(因為在我的實際代碼中,這些是我在 React 的 useReducer 鈎子中使用的動作創建者,而且可能很少,每個具有不同的返回類型)。

因此,我嘗試改用 ReturnType:

type AnyFigureFromFuncs = ReturnType<typeof getCircle> | ReturnType<typeof getSquare>
// this doesn't throw compile errors, tested on TS 4.5.2
const figure: AnyFigureFromFuncs = { figure: Figure.Circle, width: 4 }

我在這里想念什么? 謝謝。

您可以在枚舉屬性上使用as const

enum Figure {
    Circle,
    Square,
  }
  
  const getCircle = () => ({
    figure: Figure.Circle as const,
    radius: 1
  })
  
  const getSquare = () => ({
    figure: Figure.Square as const,
    width: 1
  })

  type AnyFigureFromFuncs = ReturnType<typeof getCircle> | ReturnType<typeof getSquare>
// this doesn't throw compile errors, tested on TS 4.5.2
const figure: AnyFigureFromFuncs = { figure: Figure.Circle, width: 4 }

您可以使用AnyFigure作為返回類型。

const getCircle = (): AnyFigure => ({
  figure: Figure.Circle,
  radius: 1
})

或者類型本身。

const getCircle = (): CircleType => ({
  figure: Figure.Circle,
  radius: 1
})

如果您沒有說明為什么您認為顯式返回類型會導致減速器出現問題,那么很難以我確信滿足您的標准的方式回答這個問題。 減速器肯定是相當復雜的,但是合理的返回類型是類型安全的一部分,並且在區分中可能很重要。 復雜、安全的程序根本不容易編寫。

正如問題所寫,聽起來您只是在問“如何使用一種返回類型制作工廠函數(但不必每次都對其進行注釋)? ”如果是這種情況,那么您可以使用工廠創建者像這樣:

TS Playground 鏈接

function createFigureFactory (figure: AnyFigure): () => AnyFigure {
  return () => figure;
}

const getCircle = createFigureFactory({
  figure: Figure.Circle,
  radius: 1,
});

const getSquare = createFigureFactory({
  figure: Figure.Square,
  width: 1,
});

// this is AnyFigure
type AnyFigureFromFuncs = ReturnType<typeof getCircle> | ReturnType<typeof getSquare>;

const figure: AnyFigureFromFuncs = { figure: Figure.Circle, width: 4 };
/* Error:                                                   ^^^^^^^^
   Object literal may only specify known properties, and 'width' does not exist in type 'CircleType'.(2322) */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM