Skip to content

Unstable type inference when generic is inferred from a return type #29771

Closed
@Jessidhia

Description

@Jessidhia

TypeScript Version: 3.2.4, 3.3.1, 3.4.0-dev.20190206

Search Terms: generic return

Code

declare function useDerivedState<T extends unknown>(
  initializer: (previous: T | undefined) => T
): T

function makeFoo(previous: { foo?: string } = {}) {
  return {
    ...previous,
    foo: 'bar'
  }
}

const state = useDerivedState(previous => makeFoo(previous))
state.foo

Expected behavior:

foo exists and is accessible

Actual behavior:

Very inconsistent.

This image is probably the most egregious example (state is { foo: string }):

image

But if I then type a whitespace or something to get the compiler to update, sometimes it starts seeing state as {}:

image

There are also some cases I can't screenshot properly. For example, this is the full derivation when it is almost working correctly:

image

But if I cause some input to happen, the derivation might reset to <{}>. However, pressing command to be able to use the screenshot tool causes the tooltip to update and it goes back to the full derivation.

The only thing that is consistent is that type of the previous argument seems to always be derived as {}.

Related Issues: #29638 and probably a bunch of others that look similar but don't quite show this odd / pathological behavior.


Giving makeFoo directly as the argument to the function avoids the problem but the current state is a minimum reproducible example of a problem I found that can't just be changed to that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions