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

Typescript – Dynamic value in type

Let’s assume i have a form, and I want to create a function that returns the current step name.

First step is stepOne, the second step is stepTwo, and the third step is a dynamic step that changes depending on different parameters, let’s assume some kind of id. So its base name would be dynamicStep- and it can be returned from the function as dynamicStep-123 or dynamicStep-555 for example.

I want to define the return type as accurately as possible, is there a way to do so?
something along the lines of

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

type FunctionReturnType = 'stepOne' | 'stepTwo' | 'dynamicStep-'+?

I know I can use interpolated strings in type declarations, but in this case I don’t have access to the id from outside the function

>Solution :

…and the third step is a dynamic step that changes depending on different parameters, let’s assume some kind of id…

If that ID’s value isn’t a compile-time constant or can’t be derived from the types (not values) of the parameters, then you can’t do this at compile-time. You’ll probably want to use "stepOne" | "stepTwo" | `dynamicStep-${number}`​ instead.

But if that ID’s value is a compile-time constant and it can be derived from the types of the input parameters, you can do this with a mapped type. For example:

type FunctionReturnType<ArgType extends string | number> =
    | "stepOne"
    | "stepTwo"
    | (
        ArgType extends string
            ? "dynamicStep-1"
            : "dynamicStep-2"
    );

function example<ArgType extends string | number>(arg: ArgType): FunctionReturnType<ArgType> {
    // ...
}

With that:

  • The return type of example("x") is "stepOne" | "stepTwo" | "dynamicStep-1"
  • The return type of example(42) is "stepOne" | "stepTwo" | "dynamicStep-2"
  • The return type of example(u) where the type of u is string | number is "stepOne" | "stepTwo" | "dynamicStep-1" | "dynamicStep-2"

Playground link

If you wanted example(u) in the above to return a different dynamic step rather than a union of the ones for strings and numbers, you can do that by using [ArgType] extends [string] and doing an explicit branch for number:

type FunctionReturnType<ArgType extends string | number> =
    | "stepOne"
    | "stepTwo"
    | (
        [ArgType] extends [string]
            ? "dynamicStep-1"
            : [ArgType] extends [number]
            ? "dynamicStep-2"
            : never
    );

That makes the return type of example(u) just "stepOne" | "stepTwo", it doesn’t include a union of the types for strings and numbers, by preventing the mapped type from distributing the union. (Or of course you could use "dynamicStep-3" or whatever you like instead of never.)

Playground link

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