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.
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:
Playground example
Or with an arrow function:
Playground example