Reputation: 11585
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
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
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