Ashley Coolman
Ashley Coolman

Reputation: 11585

Get "values of" union elements in TypeScript?

Given the union type:

type Valid = 'a' | 'b' | 'c'

Is it possible to extract?

const VALID_VALUES = valuesOf(Valid);
console.log(VALID_VALUES);
// ['a', 'b', 'c']

In otherwords, the opposite of typeof

Upvotes: 1

Views: 1049

Answers (2)

Ali Habibzadeh
Ali Habibzadeh

Reputation: 11558

Yes and No I would say. There is a way but I don't recommend it to be done at least completely at runtime because it makes your program slow. Maybe generate the code you need for checking and build time so you only do it once.

One solution would be to use the TS Compiler API (there is a good wrapper for this https://ts-morph.com/)

import { Project, SyntaxKind } from "ts-morph";

const project = new Project();
const source = project.addSourceFileAtPath("src/api/valid-types.ts");
const type = source.getFirstChildByKind(SyntaxKind.TypeAliasDeclaration);

if (type) {
  const props = type
    .getType()
    .getUnionTypes()
    .map((t) => t.getText().slice(1, -1));

  console.log(props); // => ["a", "b", "c"]
}

Here is a list of few project and have taken this idea to the next level

Upvotes: 3

CertainPerformance
CertainPerformance

Reputation: 370689

No, types do not exist in the emitted code, so there'd be no source from which the VALID_VALUES could be transformed from.

You could do it the other way around, though, if you're looking to make things DRY:

const VALID_VALUES = ['a', 'b', 'c'] as const;
type Valid = typeof VALID_VALUES[number];

Upvotes: 3

Related Questions