繁体   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