Reputation: 10838
I have this literal type export type names = 'n1' | 'n2' | 'n3' | 'n4' | 'n5' | 'n6';
I wonder how would you iterate that type ?
May be you can convert that type in something else and iterate that?
Should you redefine the type in a different way?
names.forEach(value => {
console.log(value);
});
Upvotes: 2
Views: 1237
Reputation: 141622
You could define it as a const and a type like this:
const names = ['n1' , 'n2' , 'n3' , 'n4' , 'n5' , 'n6'] as const;
// This produces the union type 'n1' | 'n2' | 'n3' | 'n4' | 'n5' | 'n6';
type names = typeof names[number];
// use names as a type here
const n1: names = 'n1';
console.log({
names,
n1,
// use names as an array here
mapped: names.map(name => `I am ${name}`)
});
What is going on here?
The as const
creates an array with a const context. That means the array is not a string
array but is a readonly array of specific string literal values.
Then, the typeof names[number]
uses an indexed access operator to extract those string literal values into a union type.
If we did not use as const
to define our array, then the typeof names[number]
would give us string
type instead of a union of the array's string literal values.
The end result is pretty neat. We can use names
as a union type for type checking and as an array at runtime.
Here it is in the playground, and here is the playground output in JavaScript:
"use strict";
const names = ['n1', 'n2', 'n3', 'n4', 'n5', 'n6'];
const n1 = 'n1';
console.log({
names,
n1,
mapped: names.map(name => `I am ${name}`)
});
Caveat: The use of names
as both a union type an an array value raises a question about naming conventions. Usually types are PascalCased (e.g. Names
) and values are camelCased (e.g. names
). Which naming conventions ought we to follow here?
For completeness, here is how it looks in VS Code across two files:
Upvotes: 8
Reputation: 371019
Types do not exist in the compiled code - there is nothing emitted to iterate over.
If you need the union type as shown in the question and need to be able to iterate over it as an array, first create the array as const
, and define the type as the array's values:
const arr = ['n1', 'n2', 'n3', 'n4', 'n5', 'n6'] as const;
export type names = typeof arr[number];
for (const num of arr) {
console.log(num);
}
Upvotes: 3