Creating a Typescript union, while also having runtime access to the values

I very regularly end up writing this pattern - primarily in Renovate's code - so thought I'd write it up as a form of blogumentation, so I can refer back to it in the future.

(This example uses concepts from the Renovate codebase, but does not take any code from it)

For instance, let's say that you have a known union of big Git-hosting platforms - github, gitlab and forgejo.

If you wanted to make sure that a given function parameter could only include them, you'd write i.e.

export type Platform = 'github' | 'gitlab' | 'forgejo`;

Normally this would be sufficient for usage, and nothing else is needed.

But if you then want to be able to reference the ?? - for instance, as part of generating documentation - then you need some way of accessing each of these values at runtime.

This leads us to:

export const Platforms = [
  'github',
  'gitlab',
  'forgejo',
  // no shade to other platforms
] as const; // `as const` is important!

export type Platform = (typeof Platforms)[number];

Now, you can access Platforms at runtime (and loop through them), while also enforcing the use of Platform as a function parameter.

Written by Jamie Tanna's profile image Jamie Tanna on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #typescript.

This blog post is 100% human-written, and has nothing derived from LLMs (be it code, editorial support or prose).

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.