Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to convert specific string type to lowercase in TypeScript?

I have to change a specific strings defined as 'GET' | 'POST' | 'PATCH' | 'DELETE' to lowercase, without losing information about type. When I do just method.toLowerCase(), it changes its type back to string. I have to achieve something like 'get' | 'post' | 'patch' | 'delete'. I was able to do this using Generics and Type assertion, like this:

type Method = 'GET' | 'POST' | 'PATCH' | 'DELETE';

export function request(method: Method) {
    innerRequest(toLowerCase(method))
}

function innerRequest(method: Lowercase<Method>) {
    console.log(method)
}

function toLowerCase<S extends string>(text: S) {
    return text.toLocaleLowerCase() as Lowercase<S>;
}

I would like to know if there is a better way to achieve this, without using Type assertion(as Lowercase<S>)? Or is it a good approach to use it like this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

This does not work out of the box. But you can achieve this by extending the type of toLocaleLowerCase() to be a generic:

type Method = 'GET' | 'POST' | 'PATCH' | 'DELETE';

declare global {
interface String {
    toLocaleLowerCase<T extends string>(this: T): Lowercase<T>;
}
}

export function request(method: Method) {
    innerRequest(toLowerCase(method))
}

function innerRequest(method: Lowercase<Method>) {
    console.log(method)
}

function toLowerCase<S extends string>(text: S) : Lowercase<S> {
    return text.toLocaleLowerCase();
}

What we are doing here is augmenting the type of String with a minor patch. Module augmentation is generally used to extend the types of third party libraries, but can also be used for core libraries right.

So instead of returning a string from toLocaleLowerCase, we would be returning a narrowed type based on the generic.

Playground

More info:
There is a Github thread where this is discussed in lengths here. Basically, the rationale for not adding this in the core type is that the end users of TypeScript are unblocked by using something like this. This obviously has its cons, which is mentioned in the thread like (affecting all usages)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading