2017-02-07 3 views
15

Was ist der richtige Typ für Reaktionsereignisse. Anfangs habe ich einfach nur any verwendet. Jetzt versuche ich, Dinge zu säubern und die Verwendung von any vollständig zu vermeiden.Typescript: Ereignistypen reagieren

So in einer einfachen Form wie folgt aus:

export interface LoginProps { 
    login: { 
    [k: string]: string | Function 
    uname: string 
    passw: string 
    logIn: Function 
    } 
} 
@inject('login') @observer 
export class Login extends Component<LoginProps, {}> { 
    update = (e: React.SyntheticEvent<EventTarget>): void => { 
    this.props.login[e.target.name] = e.target.value 
    } 
    submit = (e: any): void => { 
    this.props.login.logIn() 
    e.preventDefault() 
    } 
    render() { 
    const { uname, passw } = this.props.login 
    return (
     <div id='login' > 
     <form> 
      <input 
      placeholder='Username' 
      type="text" 
      name='uname' 
      value={uname} 
      onChange={this.update} 
      /> 
      <input 
      placeholder='Password' 
      type="password" 
      name='passw' 
      value={passw} 
      onChange={this.update} 
      /> 
      <button type="submit" onClick={this.submit} > 
      Submit 
      </button> 
     </form> 
     </div> 
    ) 
    } 
} 

Welche Art kann ich hier als Ereignistyp verwenden?

React.SyntheticEvent<EventTarget> scheint nicht zu funktionieren, wie ich einen Fehler, dass name und value existieren nicht auf target.

Allgemeinere Antwort für alle Ereignisse würde wirklich geschätzt werden.

Dank

Antwort

25

Die SyntheticEvent Schnittstelle ist generic:

interface SyntheticEvent<T> { 
    ... 
    currentTarget: EventTarget & T; 
    ... 
} 

Und die currentTarget ist ein Schnittpunkt der generischen Einschränkung und EventTarget.
Da Ihre Ereignisse durch ein Eingabeelement verursacht werden, sollten Sie auch FormEvent (in definition file, the react docs) verwenden.

werden sollten:

update = (e: React.FormEvent<HTMLInputElement>): void => { 
    this.props.login[e.currentTarget.name] = e.currentTarget.value 
} 
+3

Was ist ein guter Ort, um über alle gängigen Ereignistypen zu lesen? Kann nirgendwo finden. –

+0

Ereignistypen reagieren? Sie sind alle auf der [Ereignisse Seite in den Dokumenten] (https://facebook.github.io/react/docs/events.html) beschrieben. –

+3

Ich bekomme 'Name' existiert nicht auf den Typ 'EventTarget & HTMLInputElements' (TS v2.4) – Falieson

5

Das Problem ist nicht mit dem Event-Typ ist, sondern dass die Eventtarget Schnittstelle in Typoskript 3 Methoden nur hat: es richtig So

interface EventTarget { 
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; 
    dispatchEvent(evt: Event): boolean; 
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; 
} 

interface SyntheticEvent { 
    bubbles: boolean; 
    cancelable: boolean; 
    currentTarget: EventTarget; 
    defaultPrevented: boolean; 
    eventPhase: number; 
    isTrusted: boolean; 
    nativeEvent: Event; 
    preventDefault(): void; 
    stopPropagation(): void; 
    target: EventTarget; 
    timeStamp: Date; 
    type: string; 
} 

ist, dass name und value nicht existieren Ereignisziel. Was Sie tun müssen, ist das Ziel auf den spezifischen Elementtyp mit den von Ihnen benötigten Eigenschaften zu übertragen. In diesem Fall wird es HTMLInputElement sein.

update = (e: React.SyntheticEvent): void => { 
    let target = e.target as HTMLInputElement; 
    this.props.login[target.name] = target.value; 
} 

Auch für Veranstaltungen statt React.SyntheticEvent, können Sie diese auch wie folgt eingeben: Event, MouseEvent, KeyboardEvent ... etc, hängt von den Anwendungsfall des Handlers.

Der beste Weg, um alle diese Typdefinitionen zu sehen, besteht darin, die .d.ts-Dateien von beiden Typoskripten & zu überprüfen.

Auch auf den folgenden Link, um weitere Erläuterungen finden Sie unter: Why is Event.target not Element in Typescript?

+2

ps. sieht so aus, als wäre meine Typdefinitionsdatei etwas veraltet, da sie nicht die generische SyntheticEvent-Schnittstelle anzeigt. Die Antwort von Nitzan Tomer ist besser. – Edwin

+0

Ja, Nitzans Antwort scheint sauberer zu sein. Danke für die Bemühung. –

1

beide Antworten des Nitzan zu kombinieren und Edwin, fand ich, dass so etwas wie dies funktioniert für mich:

update = (e: React.FormEvent<EventTarget>): void => { 
    let target = e.target as HTMLInputElement; 
    this.props.login[target.name] = target.value; 
} 
Verwandte Themen