How to cast a String variable to a String Literal Type in Typescript
Asked Answered
S

4

32

In Typescript, suppose I want to call a function with following signature-

function foo(param: "TRUE"|"FALSE"|"NONE")

How can I do something like-

var str = runtimeString()
if(str === "TRUE" | str === "FALSE" | str === "NONE")
    foo(str)

Or, the explicit values are the only way-

var str = runtimeString()
if(str === "TRUE")
    foo("TRUE")
else if(str === "FALSE" )
    foo("FALSE")
else if(str === "NONE")
    foo("NONE")
Sawn answered 22/7, 2016 at 11:10 Comment(0)
J
15

Create a string literal type as follows:

type NullableBoolean = "TRUE" | "FALSE" | "NONE";

In the function definition, use this type for param:

function foo(param: NullableBoolean)
{
    ...
}

Make sure to cast the string to the string literal type:

var str = runtimeString();
if(str === "TRUE" || str === "FALSE" || str === "NONE")
    foo(<NullableBoolean>str);
Joselynjoseph answered 22/7, 2016 at 11:20 Comment(1)
The extra function is not needed; <NullableBoolean>str alone works as wellFraise
S
14

If you are sure that the runtime string is of one of the valid options, you can just cast your string to the type of your function that expects the string literal type.

type Tristate =  "TRUE"|"FALSE"|"NONE";

function foo(param: Tristate) {
    return "enhanced: " + param;
}

let validInput = "NONE";
foo(validInput as Tristate);

Another way to do your cast is by prepending the type like so:

foo(<Tristate> validInput);

Be aware that you override the compiler's opinion about the data in your runtime string. So at runtime there is the possibility that a value other than the defined three strings will get into your foo function.

Scales answered 22/7, 2016 at 11:28 Comment(0)
A
10

The best way I found was to create a type guard

type NullableBoolean = "TRUE" | "FALSE" | "NONE";
function foo(param: NullableBoolean)
{
    ...
}

function isNullableBool(str: string): str is NullableBoolean
{
    return str === "TRUE" || str === "FALSE" || str === "NONE"
}

if(isNullableBool(str)) { foo(str); }

This is not ideal because you have to repeat the list of values but you get a better encapsulation than with Brett's answer.

Albin answered 3/10, 2018 at 9:39 Comment(3)
You can make an array of values, and define the type and function based on the array to avoid the repetition.Raffle
@MarkSwardstrom How can I define a type based on an array?Encyst
@HAlves I added an answer so it would formatRaffle
R
2

@SimonBergot has the answer above, but this is a way to avoid the repetition in the array

const nullableBooleanValues = ["TRUE", "FALSE", "NONE"] as const;

type NullableBoolean = typeof nullableBooleanValues[number];

const isNullableBoolean = (value: unknown): value is NullableBoolean =>
  nullableBooleanValues.includes(value as NullableBoolean);
Raffle answered 17/1 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.