Consider this JavaScript function:
function foo({ a, b, c = a + b }) {
return c * 2;
}
When attempting to add type annotations in TypeScript like so:
function foo({ a, b, c = a + b }: { a?: number, b?: number, c: number }): number {
return c * 2;
}
An error is encountered:
TS2532 Object is possibly undefined
. This error occurs because the types of a
and b
are not specified as mandatory when c
is not provided.
Various methods to specify this constraint were tried, but encountered issues:
- Overloading (1):
function foo({ a, b, c = a + b }: { a: number; b: number; c: number }): number;
function foo({ c }: { c: number }): number {
return c * 2;
}
Error received:
TS2371: A parameter initializer is only allowed in a function or constructor implementation.
- Overloading (2):
function foo({ c }: { c: number }): number;
function foo({ a, b, c = a + b }: { a: number; b: number; c: number }): number {
return c * 2;
}
Error received:
TS2394: This overload signature is not compatible with its implementation signature.
This discrepancy in compatibility is puzzling, as it seems that they should be compatible.
- Conditionals
function foo({
a,
b,
c = a + b,
}: {
a: typeof c extends number ? void : number;
b: typeof c extends number ? void : number;
c: typeof a extends number ? void : typeof b extends number ? void : number;
}): number {
return c * 2;
}
Errors occured:
TS2502: 'a' is referenced directly or indirectly in its own type annotation.
TS2502: 'c' is referenced directly or indirectly in its own type annotation.
These errors make sense since TypeScript struggles with recursive references.
If anyone has insights on how to strongly type this function, please share.
Note: Altering the function's prototype for a different argument structure is acknowledged, but not desired for this exercise.