0
votes

I have a function that takes an argument with two types.

Refer to the typsescript docs, this SO question, and this SO question related to TS functions and types.

Function

  public onKeydown(ev: KeyboardEvent | EventTarget): void {
    if (ev.keyCode === 13) {
      this.sendMessage();
      ev.target.blur();
    } else {
      this.chatService.emitTyping();
    }
    return;
  }

HTML for the page

          <textarea
            autosize
            [minRows]="1"
            [maxRows]="4"
            [(ngModel)]="message"
            placeholder="escribe aqui"
            class="msg-input"
            (keydown)="onKeydown($event)"
            (click)="scrollToBottom()"
          ></textarea>

I cannot see that the function onKeyDown has two different types. Because the or doesn't seem to have the same effect in Angular as the docs of Typescript say. For example, if the 'Enter' key is pressed then blur() the keyboard and send the message. Am I going to have to make a separate function just to blur the keyboard?

This is the error I am getting:

ERROR in src/Components/chat/chat.component.ts(72,12): error TS2339: Property 'keyCode' does not exist on type 'EventTarget | KeyboardEvent'.

[ng] Property 'keyCode' does not exist on type 'EventTarget'.

[ng] src/Components/chat/chat.component.ts(74,10): error TS2339: Property 'target' does not exist on type 'EventTarget | KeyboardEvent'.

[ng] Property 'target' does not exist on type 'EventTarget'.

1
Maybe use a generic type on function parameters and cast with as later? basarat.gitbooks.io/typescript/docs/types/type-assertion.htmlJGFMK

1 Answers

2
votes

Problem is typescript is confused because what you are doing is not doable on both EventTarget and KeyboardEvent. So you should tell him directly which one is it in the function. Such as:

public onKeydown(ev: KeyboardEvent | EventTarget): void {
    if (<KeyboardEvent>ev.keyCode === 13) { // changed line
      this.sendMessage();
      ev.target.blur();
    } else {
      this.chatService.emitTyping();
    }
    return;
  }

you could also do

if ((ev as KeyboardEvent).keyCode === 13) {

note that sometimes Angular still fails to find the property you need even if it exists in the DOM object, you can then concat the types like

type KeyboardCustom = KeyboardEvent & { customProp?: string };

meaning that it is both interfaces at the same type (but the second one is purely optional, hence, it will not throw errors when lacking). You could go further with Partials.

type CustomInterface = KeyboardEvent & Partial<KeyboardInterface>

where KeyboardInterface has any kind of structure.