openapi-typescript icon indicating copy to clipboard operation
openapi-typescript copied to clipboard

Enhancing openapi-typescript for Improved Type Safety: Generating Arrays from Enum Definitions

Open nakamurau1 opened this issue 10 months ago • 7 comments

Description

I'm utilizing openapi-typescript to enhance API type safety. However, when parsing parameters using user-defined type guards, it's necessary to validate the elements of a Union type, requiring an array of Enum values. Currently, openapi-typescript only generates Union types, necessitating manual array definition, which introduces redundancy.

Proposal

I propose adding an option to openapi-typescript output to generate an array of Enum values. This would allow for the simultaneous generation of Union types and arrays, improving type safety and reducing code redundancy. For instance, consider the following option:

// Generated type definitions
type SortKey = 'id' | 'name' | 'cost';
// Proposed array
const sortKeys: SortKey[] = ['id', 'name', 'cost'];

Checklist

nakamurau1 avatar Apr 11 '24 14:04 nakamurau1

That would be very helpful!

We validate our forms with Zod to ensure that the form values match the OpenAPI spec. If the spec provides an enum with valid values, I want to pass those values to z.enum(...) to make sure that a valid value has been selected.

luchsamapparat avatar May 10 '24 09:05 luchsamapparat

I’d be open to this! While it’s still a library goal to have no runtime, technically TypeScript enums do have a runtime, so that line has been crossed already, though we do want to be reserved in what we generate (because this library tries to steer away from runtime codegen).

If anyone wants to open a PR for this, I’d like to see:

  1. The original types have the full path, e.g. const sortKeys: components["schemas"]["SortKey"][] = […]
  2. It’s behind a CLI flag (not default behavior)
  3. Lots and lots of tests 😄 (including tests that make sure that things like components["schemas"]["00-illegal-js.key"] can generate a valid JS identifier

If all 3 criteria are satisfied, happy to ship it 🙂. Just note that the current main is for the upcoming 7.x release, so if you’d like this on 6.x, base that off the 6.x branch (though a 7.0 release candidate will happen very soon, promise 😅)

drwpow avatar May 10 '24 14:05 drwpow

I started working on it and managed to emit this in packages/openapi-typescript/test/fixtures/redocly/output/b.ts for the gender enum property in openapi/b.yaml

export const personGenderValues: components["schemas"]["person"]["gender"][] = ["male", "female", "unknown"];

I also put it behind an optional CLI flag:

  --enumValues               Export union values as arrays

Not sure about the naming and description though.

I'll create a PR next week, but I have to clean up my code first and figure add tests for it.

luchsamapparat avatar May 10 '24 20:05 luchsamapparat

@drwpow I've created a PR for this: #1661

I used the enum tests as a template for testing this feature.

Also, I'm not sure about the flag's name and description and am open to suggestions for better wording.

luchsamapparat avatar May 14 '24 21:05 luchsamapparat

It would be nice to backport this to 6.x

borzaka avatar Jun 11 '24 14:06 borzaka

It would be nice to backport this to 6.x

Unfortunately I do not have time in the immediate future to add this, but I would love a PR if someone else is able to!

drwpow avatar Jun 21 '24 13:06 drwpow

Does the new --enum-values flag work for unions too or just enums? It works when I use the --enum flag but without it, running openapi-typescript just hangs and never completes.

ericljiang avatar Jul 27 '24 16:07 ericljiang