Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coverting typescript string literal types to an array of string

I have

type ImageVerticalSpacing = 'ignoreBottom' | 'ignoreTop' | 'ignoreBoth' 
| 'Default';

in typescript and need to pass those strings as an array of strings to a dropdown. How can I convert type ImageVerticalSpacing to an array of strings?

like image 543
vovina Avatar asked Aug 11 '17 03:08

vovina


People also ask

How do you convert an array into string literal union type in TypeScript?

To convert an array of strings into a string literal union type in TypeScript, you can first define the array of strings then make the array as readonly using the as const keyword, and then use the typeof operator on all the values contained in the array.

What is string [] in TypeScript?

In TypeScript, the string is an object which represents the sequence of character values. It is a primitive data type which is used to store text data. The string values are surrounded by single quotation mark or double quotation mark. An array of characters works the same as a string.

What is a literal type TypeScript?

Summary. A TypeScript string literal type defines a type that accepts specified string literal. Use the string literal types with union types and type aliases to define types that accept a finite set of string literals.


2 Answers

You can't convert types in TypeScript to values at runtime. But you can do the reverse: create a runtime object and have TypeScript infer its type.

The ideal runtime object for this purpose would be a tuple. Unfortunately, TypeScript doesn't infer tuples that well by itself. I use a helper function called tuple() which returns tuple types.

UPDATE: 2018-12, since TypeScript 3.0 the tuple() function can be written like this:

type Narrowable = string | number | boolean | symbol | 
  object | {} | void | null | undefined;
const tuple = <T extends Narrowable[]>(...args: T)=>args;

Using the above helper function, you can do this:

const imageVerticalSpacing = tuple('ignoreBottom','ignoreTop','ignoreBoth','Default');

type ImageVerticalSpacing = (typeof imageVerticalSpacing)[number];

The imageVerticalSpacing object is an array of strings you can use for your dropdown, of type ['ignoreBottom','ignoreTop','ignoreBoth','Default']. And the type ImageVerticalSpacing is the same 'ignoreBottom' | 'ignoreTop' | 'ignoreBoth' | 'Default' as you declared.

(See it in action on The Playground)

Hope that helps. Good luck!

like image 195
jcalz Avatar answered Oct 14 '22 04:10

jcalz


Building on top of jcal's answer and reiterating: "You can't convert types in TypeScript to values at runtime. But you can do the reverse: create a runtime object and have TypeScript infer its type." There is a great blog post by @steve-holgado to use const assertions for this purpose: https://steveholgado.com/typescript-types-from-arrays/

With typescript's const assertions (TypeScript 3.4+) you can do:

const animals = ['cat', 'dog', 'mouse'] as const
type Animal = typeof animals[number]

// type Animal = 'cat' | 'dog' | 'mouse'

So the question's code would look like:

const imageVerticalSpacing = ['ignoreBottom', 'ignoreTop', 'ignoreBoth', 'Default'];
type ImageVerticalSpacing = typeof imageVerticalSpacing[number];
like image 45
user3047190 Avatar answered Oct 14 '22 04:10

user3047190