Home > Blockchain >  Replacing string "true" and "false" from union type to booleans
Replacing string "true" and "false" from union type to booleans

Time:02-13

I've got one union type that is constructed from object keys, which may contain string, number, and boolean keys.

Example:

type Example = "true" | "semi" | "false"; 

What I want to achieve is to get a new type, which replaces strings true or false with actual boolean values.

type Example = true | "semi" | false;

Converting directly to boolean won't work since there might be cases where I don't have either true or false

This is what I've tried

type ReplaceTrue<T> = Extract<T, "true"> extends never ? T : Exclude<T, "true"> | true;
type ReplaceFalse<T> = Extract<T, "false"> extends never ? T : Exclude<T, "false"> | false;

type PickMyType<T> = ReplaceBoolean<T, "true", true> | ReplaceBoolean<T, "false", false>

I've also tried combining ReplaceTrue and ReplaceFalse to a single type, but I think that this would lead to a more unreadable code.

However, I feel like these solutions are not elegant and I'm wondering if there is any other method of replacing them.

CodePudding user response:

Using a mapping type:

type T1 = "true" | "semi" | "false";

type Mapping = { true: true; false: false };
type T2 = Mapping[T1 & keyof Mapping] | Exclude<T1, keyof Mapping>;
// T2 = boolean | "semi"

CodePudding user response:

This is achievable by a straightforward distributive conditional type:

type ReplBool<T> = T extends "true" ? true : T extends "false" ? false : T;

type Example = "true" | "semi" | "false";
type ReplacedExample = ReplBool<Example>;
// type ReplacedExample = boolean | "semi"
// note that boolean is an alias for true | false

You can do more complicated things involving mapped lookups or nested utility types, but the above definition is probably the tersest definition for something with just two cases.

Playground link to code

  • Related