Can someone provide assistance with type inference in TypeScript to narrow a union based on a conditional type?
Our API validates a set of parameters by normalizing all values for easier processing. One parameter can be either an array of strings or an array of arrays of strings, which is always normalized to the latter format.
To simplify and maintain the validated types, I am attempting to infer them from the incoming params using resolved values. Illustrated below:
type IncomingParams = {
names: string[] | Array<string[]> | undefined
ages: string[] | undefined
}
// Post validation the object is the following
type Validated = {
names: Array<string[]>
ages: string[]
}
The approach attempted fails to consistently return an array of arrays when there's a union:
type ArrayUnion<T> = T[] | T[][];
type Params = {
names: ArrayUnion<string>
ages: string[]
}
type ValidatedParams<P> = {
[K in keyof P]: P[K] extends ArrayUnion<infer U>
? U[][]
: NonNullable<P[K]>;
};
const validated: ValidatedParams<Params> = {} as any;
validated.names // This should be string[][]
validated.ages // This should be string[]
If TypeScript struggles to differentiate the union, one option explored is to uniquely identify ArrayUnion
, though this hasn't yielded successful results.
Your help would be greatly appreciated.