Skip to content

instanceof should not narrow in false branch; or structural assignment to class types should not be allowed #33481

Closed
@AnyhowStep

Description

@AnyhowStep

TypeScript Version: 3.5.1

Search Terms:

instanceof, narrow, false branch

Code

class A {
  x! : number
}
class B {
  y! : number
}

//Neither A nor B, nominally
//Is A, structurally
const aOrB : A|B = { x : 32 };

if (aOrB instanceof A) {
  const a : A = aOrB; //OK
} else {
  const b : B = aOrB; //Expected to fail; is OK
}

Expected behavior:

A|B should not narrow to B in the false branch.

It is possible for aOrB to structurally match A but not nominally match A.
instanceof only checks for a nominal match; not structural match.

Actual behavior:

A|B is narrowed to B in the false branch and will cause run-time bugs.

Playground Link: Playground

Related Issues:

#32774

I'm sure many people have known of this behaviour for a long time, and I never use classes or instanceof much. So, I never bothered to create an issue for it. However, the above PR finally motivated me to bring this up.

I tried to look for "instanceof narrow false branch" on the issues page but couldn't find anything related.

I'm sure this will get closed as "Working as Intended" or "Duplicate" but I feel like I needed to get this out of my system, anyway =x

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions