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 Object does not work with the in operator #51007

Closed
dragomirtitian opened this issue Sep 30, 2022 · 7 comments Β· Fixed by #51631
Closed

instanceof Object does not work with the in operator #51007

dragomirtitian opened this issue Sep 30, 2022 · 7 comments Β· Fixed by #51631
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@dragomirtitian
Copy link
Contributor

Bug Report

πŸ”Ž Search Terms

instanceof Object in

πŸ•— Version & Regression Information

  • This changed between versions 4.9.0-dev.20220919 and 4.9.0-dev.20220920

⏯ Playground Link

Playground Link

πŸ’» Code

export function isHTMLTable(table: unknown): boolean {
    return !!table && table instanceof Object && 'html' in table;
}

πŸ™ Actual behavior

Error: Type '{}' may represent a primitive value, which is not permitted as the right operand of the 'in' operator

πŸ™‚ Expected behavior

Should type check

Notes

Seems to be introduced by #50666 which correctly introduces an error if in is used on non objects. The issue is that it does not handle testing for objects with instanceof Object

@MartinJohns
Copy link
Contributor

You can just use typeof table === 'object', which will also work for objects without prototype chain (e.g. Object.create(null)).

@dragomirtitian
Copy link
Contributor Author

@MartinJohns That is the workaround I used, forgot to mention it. I still think ideally it should work.

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Sep 30, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Sep 30, 2022
@RyanCavanaugh
Copy link
Member

I think instanceof is preferable since typeof can return "function" for things that are still instanceof Object

@Andarist
Copy link
Contributor

The unknown type gets narrowed down to {} thanks to !!table. Should we then allow a {} -> object (Object?) transition through this table instanceof Object?

@RyanCavanaugh
Copy link
Member

I don't see why not -- narrowing should generally be transitive (i.e. if A -x-> C is ok then A -y-> B -x-> C should be as well)

@jcalz
Copy link
Contributor

jcalz commented Nov 11, 2022

Should we open a new issue for this problem, or does it belong here?

export function isHTMLTable<T extends object | null>(table: T): boolean {
  return !!table && 'html' in table; // error!
  // Type 'NonNullable<T>' may represent a primitive value, which is not permitted as 
  // the right operand of the 'in' operator.(2638)
}

Playground link

@Andarist
Copy link
Contributor

@jcalz I'd say that this is a different problem as the issue here, at least from my PoV, was very related to instanceof. The issue in this playground is related to generics, this one works just alright:

export function isHTMLTable(table: object | null): boolean {
  return !!table && 'html' in table;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
7 participants