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

The type checker ignores the result of 'typeof' statements assigned to variables #15859

Closed
jsepia opened this issue May 15, 2017 · 2 comments
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@jsepia
Copy link

jsepia commented May 15, 2017

TypeScript Version: 2.3.2

Code

test.js

// @ts-check

/**
 * Removes all listeners from a specified event.
 *
 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
 * @return {Object} Current instance of EventEmitter for chaining.
 * @license MIT
 * @see {@link https://github.com/Olical/EventEmitter|EventEmitter by Oliver Caldwell}
 */
function removeEvent(evt) {
  const type = typeof evt
  const events = this._getEvents()

  // Remove different things depending on the state of evt
  if (type === 'string') {
    // Remove all listeners for the specified event
    delete events[evt]
  }
  return this
}

Expected behavior:
On line 18, the type checker should know that evt is a string, from the if (type === 'string) in line 16, and it should allow the use of evt as an object key.

Actual behavior:
Error on line 18, around the variable evt: "[js] Type 'RegExp' cannot be used as an index type." This error is unhelpful since we already checked that evt is a string in line 16.

Additional notes:

This works fine:

// ...
  if (typeof evt === 'string') {
    // Remove all listeners for the specified event
    delete events[evt]
  }
// ...

But this doesn't:

// ...
  let type
  if ((type = typeof evt) === 'string') {
    // Remove all listeners for the specified event
    delete events[evt]
  }
// ...

And neither does this:

// ...
  let type = typeof evt
  if (type === 'string') {
    // Remove all listeners for the specified event
    delete events[evt]
  }
// ...
@mhegazy
Copy link
Contributor

mhegazy commented May 15, 2017

This is the same underlying cause as #10976. The compiler can not reason about relationship between values in such a fashion.
the fix is to do something like if (typeof evt === 'string') {

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label May 15, 2017
@mhegazy
Copy link
Contributor

mhegazy commented May 30, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed May 30, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

2 participants