21

I've this array:

const arr = ["foo", "bar", "loo"]

I need to convert it to a typescript type

type arrTyp = "foo" | "bar" | "loo";

How can I do this in typescript?

3
  • 1
    is the type is data type? Commented Jan 7, 2019 at 8:30
  • 1
    This might be not achievable unless TypeScript support macros. Commented Jan 7, 2019 at 8:38
  • @WongJiaHau yes it is, no macros needed, just a plain generic function :) Commented Jan 7, 2019 at 8:54

1 Answer 1

33

Edit for 3.4 and higher:

In 3.4 const assertions were added, so we can get a string literal type tuple using as const:

const arr = ["foo", "bar", "loo"] as const

type arrTyp = typeof arr[number]; // "foo" | "bar" | "loo"

Original

The problem is that arr does not preserve the literal types in the array, it will be infered to string[]. If you use a function to force the inference of string literal type, extracting the type is a simple affair:

function tuple<T extends string[]>(...o: T) {
    return o;
}
const arr = tuple("foo", "bar", "loo")

type arrTyp = typeof arr[number]; // "foo" | "bar" | "loo"

The function forces the compiler to infer a tuple of string literals for arr. So arr will be typed as ["foo", "bar", "loo"]. We can then use a type query to get a union of the elements in the tuple. You can read more about type queries here

Sign up to request clarification or add additional context in comments.

5 Comments

It works. Can you please explain typeof arr[number] a little bit? I've never seen that before. arr is now an Array. But what is arr[number]? 🙂
@Wajahath added an explanation and a link to the docs for the syntax
amazing workaround!. Hopefully, there will be a more natural way of doing this in the future
@Simon updated, with new syntax in 3.4. Thanks for drwing my attention back to this answer 😊. I have a lot of them an can't really update all of them 😔
Amazing answer, lovely Typescript :) However, as for the older answer, just out of curiosity, why does exactly "the function force the compiler to infer a tuple of string literals"?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.