I think an example is the better way to explain:
const fn = (fallback?: string) => someFnReturningStringOrUndefined() || fallback;
const result = fn('fallback'); //inferred type for `result` should be `string`, why it is `string | undefined`
If I didn't pass the fallback parameter I would understand.
CodePudding user response:
There are limits to TypeScript's code path analysis, although I think the inference of the return type will always be a union of the possible result types, even if the code path is really explicit.
If you want the result you've described, the easiest way to do it is function overloads:
function fn(a: string): string | undefined;
function fn(a: string, b: string): string;
function fn(a: string, b?: string): string | undefined {
return a || b;
}
const result1 = fn("", "fallback");
// ^? const result1: string
const result2 = fn("");
// ^? const result2: string | undefined
Or with an arrow function:
type Fn = {
(a: string): string | undefined;
(a: string, b: string): string;
};
const fn = ((a: string, b?: string) => a || b) as Fn;
const result1 = fn("", "fallback");
// ^? const result1: string
const result2 = fn("");
// ^? const result2: string | undefined
CodePudding user response:
As an extra for T.J.'s answer, you could also set a default function parameter for the fallback
prop, so it always resolves to a string.
const fn = (a: string, fallback: string = '') => a || fallback;
const result1 = fn('', 'fallback'); // typeof string
const result2 = fn(''); // typeof string