Search code examples
typescripttemplate-literals

Typescript: define a primitive within another


The issue is that when I receive a response back from an API, it is the most inconsistent response I think I've dealt with so far. Anyways, what I am trying to do is give more structure with Typescript. For example:

interface Response {
  foo: string
}

The problem that I have is that EVERYTHING is a string: foo could be "true" || "123" || "undefined" || "null"

but there are some values that I know will be there. So I know that this field will always be of type string but within that string is going to be a number

what I would like is to create a class or an interface that looks like this:

interface Response {
  foo: string<number>
}

because now I just have notes next to everything like:

interface Response {
  service: string // string("true")
}

Solution

  • Consider this example:

    type Primitives = boolean | number | null | undefined
    
    type MakeString<T extends Primitives> = `${T}`
    
    // "undefined" | "null" | `${number}` | "false" | "true"
    type Result = MakeString<Primitives>
    

    Playground

    Please see distributive-conditional-types if you are confused by T extends any

    TL;TR Wrapping T into template literal string distributes the union.

    Thanks @Clarity