Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intersection of type schema and record with enums as keys #1235

Open
alexamy opened this issue May 22, 2024 · 1 comment
Open

Intersection of type schema and record with enums as keys #1235

alexamy opened this issue May 22, 2024 · 1 comment

Comments

@alexamy
Copy link

alexamy commented May 22, 2024

How to create schema for this object?

{
  base: { version: "v1" }, // may be "v2", etc
  en: { /* lang constant */ },
  ge: { /* lang constant */ },
  fr: { /* lang constant */ },
  /* ... long list of languages ... */
}

I've found #1162 (comment), #480 (comment):

intersection([
  type({ version: enum(["v1", "v2"]) }),
  record(string() /* <-- should be enums(["en", ... ]) */, LangConstant)
])

But the problem is, as stated in the comment, that I lose list of remaining keys of the object. And even if I use enums() instead of string() as key, the schema wont validate properly (because of missing base key or wrong value type below base). So there are options:

  1. Add all languages in a object schema:
s.object({
  base: object({ version: enum(["v1", "v2"]) }),
  en: LangConstant,
  ge: LangConstant,
  /* ...other languages */
});
  1. Add helpers:
const languages = ["en", "ge", /* ...other languages */];
const langsSchema = langs.reduce((acc, lang) => {
  return { ...acc, [lang]: LangConstant };
}, {});

s.object({
  base: object({ version: enum(["v1", "v2"]) }),
  ...langsSchema,
});

But the first one have a lot of repetition, and second have a separation from superstruct.

Is there a more concise way to specify such schema?

@alexamy
Copy link
Author

alexamy commented May 22, 2024

For now I'm using a condensed option similar to 2:

const langsSchema = Object.fromEntries([
  "en", "ge", "fr",
  /* ... */
].map(lang => ([lang, s.object({
    /* ... */
  })
])));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant