17
type a = 'one' | 'two'

I would like to have a type b like

type b = 'ONE' | 'TWO'

So I tried

type a = 'one' | 'two'
type b = {[P in a]: P['toUpperCase']}

But that does not do what I want it to do.

Thank you for reading :)

4
  • 3
    I would be very impressed if this was possible. But I suspect it might not be. Commented Jun 25, 2020 at 19:08
  • 5
    Nope, no string manipulations in the type system. Commented Jun 25, 2020 at 19:34
  • The only solution I can think of is storing this type a = 'one' | 'two' on a separate file and the read the file content, then programmaticly change the values to uppercase. Commented Jun 26, 2020 at 7:32
  • 3
    @IAMTHEBEST I guess it works but seems a bit ugly. You might be able to have some sort of build step that transforms types, say takes all from lowercase.d.ts and generates an uppercase.d.ts with all the string literal types in uppercase there. But I'm not sure I really like this. Seems really easy to get in a tight bind with this if you need, say, first later capitalised only or anything other that deviates. Commented Jun 26, 2020 at 7:36

2 Answers 2

32

You can now do this with the introduction of Template Literal Types:

type A = 'one' | 'two'
type B = Uppercase<A>

let b: B = 'one' // Type '"one"' is not assignable to type '"ONE" | "TWO"'.

TS Playground

In addition to Uppercase<StringType>, there are also the following helper types:

  • Lowercase
  • Capitalize
  • Uncapitalize

They can be used within a Template Literal Types, like below:

type Fruit = 'Apple' | 'Banana'
type FruitField = `fr_${Uncapitalize<Fruit>}`

const fruit: Record<FruitField, boolean> = {
    'fr_apple': true,
    'fr_banana': false,
    'fr_Apple': true, // error
    'fr_peach': false // error
}

TS Playground

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

2 Comments

The syntax has changed slightly for v4.1.0 beta, it's now {uppercase A}. typescriptlang.org/play?ts=4.1.0-beta#code/…
With release v4.2 it's switched back to the way OP originally wrote it
5

Here you have the link to TS Playground

And here the code:

type A = 'one' | 'two'
type B = Uppercase<A>

let b: B = 'one' // Error

P.S. I don't get why in the previous comment has been used a more complicated form to write the same thing

EDIT: Derek Nguyen (best answer) has now changed his answer with the newer and more simple solution.

1 Comment

Thanks for pointing that out, IIRC during the 4.1 beta the manipulation types (uppercase<>, lowercase<>, etc.) only worked within the template literal

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.