Skip to content

instanceof AbstractClass.constructor should narrow to typeof AbstracClass #28936

Open
@karfau

Description

@karfau

Please try to reproduce the issue with typescript@next. It may have already been fixed.

TypeScript Version: 3.3.0-dev.20181208

Search Terms: static instanceof constructor

Code

type Meta = {foo: string};
abstract class Abstract {
  static meta: Meta;
  public abstract toString(): string;
}

const getMeta = (fromModule: any): Meta | undefined => {
  return fromModule instanceof Abstract.constructor
    ? fromModule.meta : undefined;
};

Expected behavior:
Narrow the type of fromModule to typeof Abstract, so that static fields can be accessed.
(In Typescript versions <= 3.1.6 the above code didn't raise an error, my guess is that the type was not narrowed at all)

Actual behavior:
The narrowed type of fromModule is {}:

Error:(10, 18) TS2339: Property 'meta' does not exist on type '{}'.

Playground Link:
https://www.typescriptlang.org/play/index.html#src=%0D%0Atype%20Meta%20%3D%20%7Bfoo%3A%20string%7D%3B%0D%0Aabstract%20class%20Abstract%20%7B%0D%0A%20%20static%20meta%3A%20Meta%3B%0D%0A%20%20public%20abstract%20toString()%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Aconst%20getMeta%20%3D%20(fromModule%3A%20any)%3A%20Meta%20%7C%20undefined%20%3D%3E%20%7B%0D%0A%20%20return%20fromModule%20instanceof%20Abstract.constructor%0D%0A%20%20%20%20%3F%20fromModule.meta%20%3A%20undefined%3B%0D%0A%7D%3B%0D%0A

Related Issues:
I found the following potentially related issues but they didn't seem to be an exact match or to old (because this problem only exists since 3.2.1):
- #27276
- #23274
- #16035

Workaround
Creating a type guard is of course doable for a single abstract class.

const extendsAbstract = (FromModule: unknown): FromModule is typeof Abstract =>
  FromModule && FromModule instanceof Abstract.constructor;

(Or maybe it could even be written in a generic way?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions