Search code examples
typescripttypescript-genericsunion-typestypescript-types

Check whether union types in typescript are data types or string values


Let's say we have a generic type that tests union types and determines whether they are string or data types, so that if any of the types is string value, it should return 'string' or if union types are primitive types, it should return 'primitive':

type PrimitiveDataType = 'primitive';
type StringValue = 'string';

type Selector<T> = T extends string ? StringValue : PrimitiveDataType;

type StringCheck = Selector<'boo' | 'bar'>; // to be 'string'
type PrimitiveCheck = Selector<string | number>; // to be 'primitive'

In the above example the 'PrimitiveCheck' type yield "string" | "primitive" but it should be primitive.

What is the best way to solve this?


Solution

  • type Selector<T> = Exclude<T, string> extends never ? 'string': 'primitive'; 
    

    However, I'm not sure how nicely this is going to play/scale if you have multiple types you want to declare like this.

    Explanation

    We're using the Exclude type essentially to check if there are any types other than string in the union. If there are not, the type is 'string'.