Inference problem: "...referenced directly or indirectly in its own initializer"

Viewed 2071

I reduced an issue I hit today into this minimal example. (playground link)

function test() {
    interface Foo<T> {
        type: 'Bar'
    }

    function nextFoo<T>(it: Foo<T>): Foo<T> {
        return it
    }

    let foo: Foo<string> | undefined = { type: 'Bar' }
    while (foo !== undefined) {
        // Type inference error here but TS has the correct inference when hovering over nextFoo
        const next = nextFoo(foo) 
        foo = next // commenting this out masks the issue
    }
}

This seems like something that TypeScript should be able to handle. When I hover over nextFoo in vscode it does look like it correctly infers the type there. Something about setting foo to next while it can potentially be undefined results in this.

Could someone explain what's going on here?

1 Answers

As a workaround, you could strongly type your next variable:

function test() {
    interface Foo<T> {
        type: 'Bar'
    }

    function nextFoo<T>(it: Foo<T>): Foo<T> {
        return it
    }

    let foo: Foo<string> | undefined = { type: 'Bar' }
    while (foo !== undefined) {
        // Type inference error here but TS has the correct inference when hovering over nextFoo
        const next: Foo<string> | undefined = nextFoo(foo) 
        foo = next // commenting this out masks the issue
    }
}
Related