There seems to be inconsistency in how the TypeScript compiler handles parametrised types. Sometimes it raises an error if a type is not passed, other times it doesn't, and the reasoning behind this behavior is unclear.
It appears that the structure of the function may influence whether the compiler can infer the type T
, but there are instances where this assumption does not hold true.
Several experiments were conducted to test this theory:
Experiment 1
function cannotBeInferred<T>(): T { return 0 as T; } const a1 = cannotBeInferred(); const a2 = cannotBeInferred<string>();
- Variable
a1
is inferred asunknown
; an unexpected outcome - Variable
a2
is correctly inferred asstring
- Variable
Experiment 2
function canBeInferredNativeType<T>(par: T): T { return par; } const b1 = canBeInferredNativeType('test'); const b2 = canBeInferredNativeType<string>('test');
- Variable
b1
is of type"test"
, which should generate an error - Variable
b2
is correctly inferred asstring
- Variable
Experiment 3
function canBeInferredInterface<T>(param: { something: T }): T { return param.something; } interface Something { something: string }; const param: Something = { something: 'blabla' }; const c1 = canBeInferredInterface({ something: 'test' }); const c2 = canBeInferredInterface(param); const c3 = canBeInferredInterface<number>({ something: 123 });
- Variable
c1
is inferred asstring
, despite potential ambiguity - Variable
c2
is also inferred asstring
, which could benefit from clearer error handling - Variable
c3
is correctly inferred asnumber
- Variable
This inconsistency calls for a more uniform approach. Is there a compiler option available to achieve this?