π Search Terms
"contextual typing of function return values" "function return error in the wrong place"
β
Viability Checklist
β Suggestion
Often when writing a function where the return type should be known, errors appear overly complicated and far away from their source.
type Ret = {a: number};
type Fn = () => Ret;
const issue: Fn = () => {
// ^ it shows the error here: Type '() => { a: string; }' is not assignable to type '() => { a: number; }'.
return {a: "25"};
// ^ instead of here
};
// adding an explicit return type fixes it
const workaround1: Fn = (): Ret => {
return {a: "25"};
// ^ shows here: Type 'string' is not assignable to type 'number'.
};
// returning without a block body fixes it
const workaround2: Fn = () => ({a: "25"});
// ^ shows here: Type 'string' is not assignable to type 'number'.
// using a helper function fixes it
function inferRet<T>(arg: NoInfer<T>): T {
return arg;
}
const workaround3: Fn = () => {
return inferRet({a: "25"});
// ^ shows here: Type 'string' is not assignable to type 'number'.
};
Unfortunately, this would be a breaking change as it would cause some existing working code to now error, so it would have to be added under a compiler flag or wait for 7.0/8.0:
const breaking: Fn = () => {
return {a: 25, b: 56};
// ^ previously, there would be no error here.
// with this change: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
};
Playground link
π Motivating Example
interface App {
start: () => {
title: {
name: string,
},
},
}
export const app: App = {
start: () => {
return {
title: {
name: 25,
},
};
},
};
Playground link
Previously, the error would show as:
10 | start: () => {
~~~~~
Type '() => { title: { name: number; }; }' is not assignable to type '() => { title: { name: string; }; }'.
Call signature return types '{ title: { name: number; }; }' and '{ title: { name: string; }; }' are incompatible.
The types of 'title.name' are incompatible between these types.
Type 'number' is not assignable to type 'string'.(2322)
input.tsx(2, 5): The expected type comes from property 'start' which is declared here on type 'App'
With this change, the error will show as:
13 | name: 25,
~~~~
Type 'number' is not assignable to type 'string'.(2322)
input.tsx(2, 5): The expected type comes from property 'name' which is declared here on type '{ name: string; }'
The second one is clearly easier to read and fix
π» Use Cases
- What do you want to use this for?
Interfaces that define functions with return types
- What shortcomings exist with current approaches?
workaround 1: Explicitly setting the return type is annoying, and shouldn't need to be done when typescript clearly knows what it should be.
workaround 2: Not using a block body is often not reasonable when computation needs to be done in the body of the function.
workaround 3: You shouldn't need to define a helper function for this
- What workarounds are you using in the meantime?
Every time I define a function where the return type could be inferred, I always specify it manually to make the errors easier to read.
π Search Terms
"contextual typing of function return values" "function return error in the wrong place"
β Viability Checklist
β Suggestion
Often when writing a function where the return type should be known, errors appear overly complicated and far away from their source.
Unfortunately, this would be a breaking change as it would cause some existing working code to now error, so it would have to be added under a compiler flag or wait for 7.0/8.0:
Playground link
π Motivating Example
Playground link
Previously, the error would show as:
With this change, the error will show as:
The second one is clearly easier to read and fix
π» Use Cases
Interfaces that define functions with return types
workaround 1: Explicitly setting the return type is annoying, and shouldn't need to be done when typescript clearly knows what it should be.
workaround 2: Not using a block body is often not reasonable when computation needs to be done in the body of the function.
workaround 3: You shouldn't need to define a helper function for this
Every time I define a function where the return type could be inferred, I always specify it manually to make the errors easier to read.