microsoft / microsoft/TypeScript

Type inference only works on the same line as the variable declaration

Offen
#41,289 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

In Discussion Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

I ran into this odd behavior while writing some tests, that do the typical describe, declare a closure-scope variable, and in beforeEach, assign some object to that variable that is used in each of the tests inside.

Search Terms:
infer, inference, closure, scope, broken, any, cast

Initially, I thought it was limited to closure scope, but I then started reducing the reproduction sample more and more, and realized, it's broken even if it's on the very next line:

Code

// given
interface Foo {
    id: string;
}

function make(): Foo {
    return {
        id: 'akatechis',
    }
}

// u1 is correctly inferred to be of type Foo.
let u1 = make();

// u2 is incorrectly inferred to be of type any.
let u2;
u2 = make();

// this was the scenario in which I originally ran into this:
// a closure scoped variable that is assigned in an inner function
function outer () {
    // u3 is inferred to be of type any
    let u3;
    return {
        inner() {
            // u3 here is still any
            u3 = make();

            // surprisingly, returning u3 here causes the return type of inner() to be Foo, not any???
            return u3;
        }
    }
}

Expected type declarations:

interface Foo {
    id: string;
}
declare function make(): Foo;
declare let u1: Foo;
declare let u2: Foo; // <---- this should have been inferred to be Foo
declare function outer(): {
    inner(): Foo;
};

Actual type declarations:

interface Foo {
    id: string;
}
declare function make(): Foo;
declare let u1: Foo;
declare let u2: any;
declare function outer(): {
    inner(): Foo;
};

Playground Link: playground

Related Issues:
The only thing that I found somewhat close to this issue was the question in the FAQ about unused generic types causing type widening, but I don't think this is it, because I'm not using generics here.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der verlinkten TypeScript Playground-Reproduktion und vergleiche die abgeleiteten Deklarationen für u1, u2 und outer(). Lies den zugehörigen FAQ-Eintrag über Type Widening, um diese Erklärung auszuschließen, und ermittle anschließend das für die Abweichung verantwortliche Verhalten der Typinferenz. Als erledigt gilt die Aufgabe, wenn u2 als Foo abgeleitet wird und dabei das gezeigte Ergebnis von outer() erhalten bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.