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

Reflect.has fails to act as type guard (should act same as "in" operator) #30688

Open
lukewlms opened this issue Apr 1, 2019 · 2 comments
Open
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@lukewlms
Copy link

lukewlms commented Apr 1, 2019

TypeScript Version: ^3.4.0-dev.20190330

Search Terms:
Reflect.has
in operator

Code

const test1 = (a: { field: number } | {}) => (("field" in a) ? a.field : 0);

const test2 = (a: { field: number } | {}) => Reflect.has(a, "field") ? a.field : 0;

Expected behavior:
Both compile successfully. "in" operator acts as a type guard per #10485. Reflect.has should act the same as "in" operator here.

We'd like to use Reflect.has a lot more and this case holds us back. Thank you!

Actual behavior:
"in" operator line compiles; Reflect.has line does not compile. Error:

allPasos.ts:445:31 - error TS2339: Property 'field' does not exist on type '{} | { field: number; }'.
Property 'field' does not exist on type '{}'.

445 Reflect.has(a, "field") ? a.field : 0;

Playground Link:

https://goo.gl/2R4dkS

Related Issues:

#10485

@dragomirtitian
Copy link
Contributor

This could be a definition of has that would work as you expect:

declare namespace Reflect {
  function has<T, K extends PropertyKey>(target: T, propertyKey: K): target is Extract<T, Record<K, any>>;
}
const test2 = (a: { field: number } | {}) => Reflect.has(a, 'field') ? a.field : a;

As a workaround you could add it yourself.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Experience Enhancement Noncontroversial enhancements labels Apr 1, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Apr 1, 2019
@lukewlms
Copy link
Author

lukewlms commented Apr 2, 2019

Looks like that does work as a stopgap! Thanks for the suggestion, added that in our custom types code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants