Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instanceof AbstractClass.constructor should narrow to typeof AbstracClass #28936

Open
karfau opened this issue Dec 10, 2018 · 1 comment
Open
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@karfau
Copy link

karfau commented Dec 10, 2018

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?)

@weswigham
Copy link
Member

Ref #3841, which is related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants