How can I extract a type from a union of (Type | Type[]) to get Type?

Viewed 38

I'm trying to get the type of an exported union type by the array of it inside as represented in the playground above. What would be the best way to do this without using the Type itself (as it is non-exported)?

interface CurrentType {
  a: string;
  b: number;
}

type ExportedType = CurrentType | CurrentType[]

type DesiredType = CurrentType

// How can I get to DesiredType from CurrentType?

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgMIFcpQuAKgTwAcUBvAWAChlk4AuZAZzClAHMBuS6gI3pHQC23aJwoBfSpTBEUAUQAehAPZRIAEwLFkAXjSZseGcgA+erDjCaIAbQC6kitK0ARCA2DYNR3RnOHiDgD0gcgAEkoA7sgIcCDIAJLIrBBgyGBKyK7unlbIMFBKAmYGljIA-EA

2 Answers

Exclude arrays of unknown type from the union

type DesiredType = Exclude<ExportedType, Array<unknown>>

You can create a utility which will operate on a type, extracting from each of its array constituents a union of its members:

TS Playground

type ArrayElementOrType<T> = T extends readonly any[] ? T[number] : T;

This has the advantage of working on other unions of different "base" types:

type AnotherExportedType = number | string[];

type NorS = ArrayElementOrType<AnotherExportedType>;
//   ^? string | number

and in your case, it simply collapses into your desired target type:

type TargetType = ArrayElementOrType<ExportedType>;
//   ^? CurrentType
Related