Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is widening of a function return type in typescript

Tags:

typescript

I have noticed this behaviour in typescript

interface Foo {
  x: () => { x: 'hello' };
}

const a: Foo = {
  x: () => {
    return {
      x: 'hello',
      excess: 3, // no error
    }
  },
}

I found some issues in github that state that this is because of function return type widening.

What does function return type widening mean?

like image 603
dagda1 Avatar asked Dec 01 '25 02:12

dagda1


1 Answers

Excess property checks don't kick in unless you directly assign a value to a reference of a specified type. So unless you directly assign the object literal to a parameter or variable or return that are explicitly typed you will not get an error.

In this case the x function is typed independently as part of determining the type of the outer object literal and it's return type is determined to be { x: 'hello', excess: 3 }. Then this function is checked for compatibility with the x in Foo and is found to be compatible. At no point was a direct assignment of the object literal to an explicitly typed reference checked. And thus no excess property checks triggered.

The widening that you found in the issues doesn't play into the absence of an error here IMO. The compiler uses contextual types to determine some types. So for example it will use the fact that the outer object literal is assigned to a Foo reference as the context, and this will help in determining parameter types for example, and it will stop the widening of { x: "hello" } to { x: string }, but it will not trigger excess property checks.

Not saying this is the way it should work, and I have seen a lot of questions that revolve around this exact issue, the lack of excess property checks when retuning an object literal from a function that in theory has its return type determined by the context it's declared in.

like image 127
Titian Cernicova-Dragomir Avatar answered Dec 06 '25 07:12

Titian Cernicova-Dragomir