Tengo una enumeración y dos funciones que devuelven diferentes tipos de datos:
enum Figure { Circle, Square, } const getCircle = () => ({ figure: Figure.Circle, radius: 1 }) const getSquare = () => ({ figure: Figure.Square, width: 1 }) Quiero tener un tipo de unión AnyFigure para poder usar círculos y cuadrados en combinación. Puedo hacerlo definiendo ambos tipos:
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 }Esto funciona bien, pero no quiero definir el tipo de retorno de cada función "obtener figura" (porque en mi código real esos son creadores de acciones que uso en el gancho useReducer de React, y podría haber bastantes de ellos, cada uno con diferente tipo de retorno).
Por lo tanto, traté de usar ReturnType en su lugar:
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 }¿Que me estoy perdiendo aqui? Gracias.
Simplemente puede usar as const en las propiedades de enumeración:
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 }Sin que muestre por qué cree que los tipos de retorno explícitos causan un problema con sus reductores, es difícil responder esto de una manera en la que esté seguro de que satisface sus criterios. Los reductores definitivamente pueden ser bastante complejos, pero los tipos de retorno de sonido son parte de la seguridad de tipos y pueden ser importantes en la discriminación. Los programas complejos y seguros simplemente no son fáciles de escribir.
Tal como está escrita la pregunta, parece que solo está preguntando " ¿Cómo puedo hacer funciones de fábrica con un tipo de retorno (pero no tener que anotarlo cada vez)? " Si ese es el caso, entonces puede usar un creador de fábrica como esto:
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) */Puede usar AnyFigure como tipo de devolución.
const getCircle = (): AnyFigure => ({ figure: Figure.Circle, radius: 1 })O el tipo en sí.
const getCircle = (): CircleType => ({ figure: Figure.Circle, radius: 1 })