Supongamos que queremos registrar el atributo ID de un elemento en el que se hizo clic con el siguiente código TypeScript:
onClick(event) { console.log(event.target.attributes.id.nodeValue); } La función anterior recibe el objeto en el que se hizo clic como parámetro, pero el tipo en este caso es any . Si compruebo el resultado del tipo de typeof event , obtengo object . Así que modificaría mi código de la siguiente manera:
onClick(event: object) { console.log(event.target.attributes.id.nodeValue); }En este caso, recibo un error en VS Code como se muestra a continuación:
Entonces, ¿qué pasa con esto? Usando type any como tipo de parámetro funciona, la consola registra la ID deseada sin ningún error, pero si decido usar un object estricto como tipo de parámetro, mi código no se compila. ¿Dónde está el problema?
El código HTML afectado es el siguiente;
<h1 id="foo" (click)="onClick($event)">...</h1>Si compruebo el resultado del tipo de
typeof event, obtengoobject.
Ese es el código de tiempo de ejecución, por lo que es el tipo de operador de typeof , que dice "object" para todos los objetos (y null ).
Así que modificaría mi código de la siguiente manera ... Recibo un error que es VS Code como el siguiente
Los objetos simples no tienen una propiedad de target .
El tipo de objeto de evento para un evento de click es MouseEvent . (Ha etiquetado jquery y angular . Si está usando jQuery o el DOM para adjuntar el evento, será el MouseEvent del DOM . Si está usando Angular para adjuntar el evento,parece que también será el MouseEvent del DOM. Advertencia: no uso Angular.) Probablemente también desee event.currentTarget.id o event.target.id en lugar de usar la colección de attributes y nodeValue , ya que el atributo id es una propiedad reflejada.
Pero , la interfaz MouseEvent del DOM hereda su propiedad currentTarget de Event , que simplemente la define como EventTarget . Sabes que será un Element , pero desafortunadamente la interfaz solo dice que es EventTarget . (Lo mismo es cierto para target ).
Hasta donde yo sé, no hay una interfaz predefinida para un MouseEvent que defina currentTarget como Element en su lugar. Puede usar de manera confiable (en esta situación) una aserción de tipo:
onClick(event: MouseEvent) { console.log((event.target as Element).id); // Or `(event.currentTarget as Element).id` }No me gustan las aserciones tipográficas, pero a veces son necesarias.
A veces ves a personas haciendo la misma afirmación de forma ligeramente diferente, como esta:
onClick({target}: {target: Element}) { console.log(target.id); } // or onClick({currentTarget}: {currentTarget: Element}) { console.log(currentTarget.id); }En su lugar, puede crear un tipo reutilizable, como este:
interface ElementMouseEvent extends MouseEvent { currentTarget: Element; target: Element; }... y luego úselo (que todavía está haciendo una afirmación, pero nuevamente, segura):
onClick(event: ElementMouseEvent) { console.log(event.target.id); // Or `event.currentTarget.id` }