ReactiveX / rxjs

A reactive programming library for JavaScript
https://rxjs.dev
Apache License 2.0
30.73k stars 3k forks source link

Observable.fromEvent(input, 'evt').map: Property 'target' does not exist on type '{}' #1822

Closed squarewave24 closed 8 years ago

squarewave24 commented 8 years ago

following the Angular2 QuickStart setup, I've added following code:

my code:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { DataService } from './DataService';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';

compilation error happens here. Not sure how to troubleshoot this:

ngAfterViewInit() {
    var keyups = Observable.fromEvent(this.input.nativeElement, 'keyup')
        .map( e => {
            // typescript: Property 'target' does not exist on type '{}'
            return e.target.value;
        })

I have a feeling it's just a matter of telling TypeScript where to find the definition for the event, but all the examples i've found so are pretty much do the same imports

package.json

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common":  "2.0.0-rc.1",
    "@angular/compiler":  "2.0.0-rc.1",
    "@angular/core":  "2.0.0-rc.1",
    "@angular/http":  "2.0.0-rc.1",
    "@angular/platform-browser":  "2.0.0-rc.1",
    "@angular/platform-browser-dynamic":  "2.0.0-rc.1",
    "@angular/router":  "2.0.0-rc.1",
    "@angular/router-deprecated":  "2.0.0-rc.1",
    "@angular/upgrade":  "2.0.0-rc.1",
    "systemjs": "0.19.27",
    "core-js": "^2.4.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12",
    "angular2-in-memory-web-api": "0.0.11",
    "bootstrap": "^3.3.6"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.2.0",
    "typescript": "^1.8.10",
    "typings":"^1.0.4"
  }
}
kwonoj commented 8 years ago

It's because nativeElement does not exposes any type information (https://angular.io/docs/js/latest/api/core/index/ElementRef-class.html#!#nativeElement-anchor), leaves consumer to correctly infers type for each DOM element as necessarily.

You may able to cast nativeElement to corresponding eventemitter type (https://github.com/ReactiveX/rxjs/blob/c76a14d4e236139076db94086648bdbce88b2e15/src/observable/FromEventObservable.ts#L7-L35), or cast event to any to access its properties without type information.

squarewave24 commented 8 years ago

thanks! i tried casting it like this, but it's not helping.

  var keyups = Observable.fromEvent(this.input.nativeElement as any, 'keyup')
        .map( e  => {
            return e.target.value; // <-- target does not exist on {}
        })
kwonoj commented 8 years ago

this.input.nativeElement as any isn't typescript syntax to cast.

https://www.typescriptlang.org/docs/handbook/basic-types.html

squarewave24 commented 8 years ago

maybe it's a newer feature ? https://basarat.gitbooks.io/typescript/content/docs/types/type-assertion.html

squarewave24 commented 8 years ago

any way you can give me an example of how to do it in my situation? i tried casting the argument parameter as well

kwonoj commented 8 years ago

Main reason in here is nativeElement is already none-type inferrable, as nativeElement: any. So casting it again to <any>nativeElement is redundant.

As commented above, you could go with 2 options (https://github.com/ReactiveX/rxjs/issues/1822#issuecomment-231903246)

or if would like to shortest workaround to make compiler don't worry about types, you may also able to try map((e: any) => {...}) to bypass compiler.

kwonoj commented 8 years ago

As I believe this isn't erroneous behavior of current type definition of operators, let me close this issue. If you think there is incorrect behavior in library, please feel freely reopen / or file new issue with minimal codebases can reproduce issue (via small jsfiddle, or github repo, etcs)

squarewave24 commented 8 years ago

thanks for responding so quickly! As you likely already guessed I am new to Typescript :)

thanks again

squarewave24 commented 8 years ago

I tried a few approaches and finally got rid of the nativeElement as a test, and the same error persists. this leads me to believe it was not the nativeElement all along.

var $input = $('#Search');
    var keyups = Observable.fromEvent($input, 'keyup')
        .map( e => {
            return e.target.value; // [ts] Property 'target' does not exist on type '{}'.
        })
billba commented 7 years ago

Better late than never, I believe the syntax you're looking for is Observable.fromEvent<KeyboardEvent>($input, 'keyup').

jochenshi commented 7 years ago

maybe you can try using this: e['target'].value, that works for me.

xgz123 commented 7 years ago

TS7017: Element implicitly has an 'any' type because type '{}' has no index signature. @jochenshi I got this with e['target']

lock[bot] commented 6 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.