Reputation: 556
I want to make last arg of function conditionally optional, eg. if previous argument has type null, make last optionial (?
), if previous has value, make last arg required.
Is this possible?
Upvotes: 0
Views: 129
Reputation: 330116
You could use a union of rest tuples to give you this behavior:
const func = (...param: [null, unknown?] | [unknown, unknown]) => {};
func("a", "b"); // okay
func("a"); // error! Type 'string' is not assignable to type 'null'.
func(null); // okay
func(null, "b"); // okay
Or, you could use the traditional (pre-TS3.0) solution to this, overloads:
const func: {
(param1: null, param2?: unknown): void; // first call signature
(param1: unknown, param2: unknown): void; // second call signature
} = (param1: unknown, param2?: unknown) => {};
func("a", "b"); // okay
func("a"); // error! Type '"a"' is not assignable to parameter of type 'null'.
func(null); // okay
func(null, "b"); // okay
Either of those should work for you. Hope that helps; good luck!
Upvotes: 1
Reputation: 29093
I think this is better expressed as two mutually exclusive parameter objects. You can define two (or more) types that your function expects.
null
. For ease, I will also make the value optional:interface SingleParamObject {
param1?: null
}
null
:interface TwoParamObject<T1, T2> {
param1: NonNullable<T1>,
param2: T2
}
This is a bit more typing for this case, at least but I think it addresses the problem more comprehensively - you either want to pass a parameter object with param1
either missing or null
or you want both param1
and param2
:
const func = <T1, T2>(params: SingleParamObject|TwoParamObject<T1, T2>) => {};
This makes it more expressive what you want to do and you can also add more shapes for parameter objects - perhaps you want nothing, or param1
+ param2
, or param1
+ param2
+ param3
+ param4
, or whatever combinations you want.
Check on TypeScript Playground
Upvotes: 0