I would like to disable the distribution of union types over conditional types in certain cases. If this is already possible (not sure about that) it should be documented in a better way.
Suppose you would like to infer type parameters like so:
````ts
type Route = {
Path: string;
Params: { [key: string]: string }
}
type RouteWithParams
Path: string;
Params: { [key in T]: string }
}
type RouteWithParamsMaker
? U extends string
? RouteWithParams
: never
: never;
function toRouteWithParams
return (r as unknown) as RouteWithParamsMaker
}
const route = {
Path: 'somewhere',
Params: { id: 0, name: 1 },
}
const routeWithParams = toRoute(route);
````
The resulting variable is currently inferred to have the type
ts
RouteWithParams<"id"> | RouteWithParams<"name">
Instead, I would like to receive the following type
ts
RouteWithParams<"id" | "name">
I have no idea whether the current behaviour is intentional (and we would need a new annotation for such cases) or a bug.
My suggestion meets these guidelines (not sure about the first and the last one):
So.... I just found out that I actually can circumvent the distribution if I change RouteWithParamsMaker:
ts
type RouteWithParamsMaker <T extends Route> = (keyof T['Params']) extends infer U
? RouteWithParams<Extract<U, string>>
: never;
This came a bit as a surprise - my initial feeling was that it should behave equally. So I guess one way to avoid the distribution is to extract conditionals in a clever way to new types. I would really like to have better guidance as a programmer here.
To avoid distribution: wrap any naked type parameters in a 1-tuple, and do the same for the check type.
type RouteWithParamsMaker<T extends Route> = (keyof T['Params']) extends infer U
? [U] extends [string]
? RouteWithParams<U>
: never
: never;
I don't believe this is in the TypeScript handbook, but it probably should be.
Tag for searching purpose: distributive conditional type trouble
Most helpful comment
To avoid distribution: wrap any naked type parameters in a 1-tuple, and do the same for the check type.
I don't believe this is in the TypeScript handbook, but it probably should be.
Tag for searching purpose: distributive conditional type trouble