Can anyone please explain to me why ReturnType
can infer a function's exact return values when there's an if
statement, but only can infer types of the value when the function returns one guaranteed string or number value?
In testA
, ReturnType<typeof testA>
could successfully infer the return values, 1 and 2.
However, in the case of testB
(return one value), ReturnType<typeof testB>
can only infer the type, number
.
Why a function that returns only can guess literally the type of the return value which is number
It behaves the same with string
values. (second screenshot)
This is related to type widening
The following resources will be useful:
An explicit excerpt from the above PR outlines the behaviour observed
In a function with no return type annotation, if the inferred return type is a literal type (but not a literal union type) and the function does not have a contextual type with a return type that includes literal types, the return type is widened to its widened literal type:
function foo() { return "hello"; } function bar() { return cond ? "foo" : "bar"; } const c1 = foo(); // string const c2 = bar(); // "foo" | "bar"
A couple of simple ways to address this are:
as const
on the functions return valuereturn 1
satisfies the return type constraint, there is no need for inferrence and thus potential widening)const testA = (v: boolean) => v ? 1 : 2; // (v: boolean) => 1 | 2
const testB = (v: boolean) => 1; // (v: boolean) => number
const constTestB = (v: boolean) => 1 as const; // (v: boolean) => 1
const typedTestB = (v: boolean): 1 => 1; // (v: boolean) => 1