Skip to content

Wrong type inference for block scoped variables #42146

Closed
@DavideCanton

Description

@DavideCanton

TypeScript Version: 4.1.3

Search Terms: inference, variable, block, wrong

Expected behavior:
It should compile just fine.

Actual behavior:
Compilation error on row 16 due to wrong inference of variable.

Related Issues: not found

Code:

function setToTrue(func: (v: boolean) => void) {
    func(true);
}

function expect<T>(v: T): { toEqual: (t2: T) => void } {
    return {
        toEqual: v2 => {
            if (v !== v2) throw new Error('different values');
        }
    };
}

function foo() {
    let b: boolean | null = null;    
    setToTrue(x => b = x);
    expect(b).toEqual(true);
}
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": 2,
    "target": "ES2017",
    "jsx": "React",
    "module": "ESNext"
  }
}

Playground Link: Provided

Type inference for variable "b" at row 14 is wrong, even if I specify explicitly "boolean | null". The compiler is unable to understand that b is effectively assigned immediately at line 15, and I find it to be correct, but it also infers that the actual type of the variable is just "null" and not "boolean | null" as I provided.
As a result, the code at line 16 (which I loosely borrowed from jasmine), does not compile, as the expect function is unable to get the property generic type instantiation, because T gets replaced with "null".

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions