I am trying to create a TypeScript type that will represent either a VoidFunction
or a function with a single parameter based on a provided generic.
Using a conditional, the type looks like this:
type VoidFunctionOrWithParams<Params> = Params extends void
? VoidFunction
: (params: Params) => void;
An example usage might look like this:
type WithStringParams = VoidFunctionOrWithParams<'one' | 'two'>;
Expected Result Type
(params: 'one' | 'two') => void
Actual Result Type
((params: "one") => void) | ((params: "two") => void)
Why does TypeScript interpret this as two separate functions with no overlap? Is there a way around this? What I really want is one function type where params
could be any of the values in the union - not different function types.
CodePudding user response:
You are seeing the effects of conditional distributive types here. To avoid distribution, you can wrap the generic type in a tuple.
type VoidFunctionOrWithParams<Params> = [Params] extends [void]
? VoidFunction
: (params: Params) => void;
type WithStringParams = VoidFunctionOrWithParams<'one' | 'two'>;
// type WithStringParams = (params: "one" | "two") => void