¿Por qué no limita “typeof” un tipo de unión cuando el tipo de una propiedad es un discriminante?
Si los miembros de un tipo de unión comparten una propiedad, y el tipo de esa propiedad se puede utilizar para discriminar entre esos miembros, debería poder reducir el tipo dentro de una cláusula if
utilizando typeof
como condición. Pero no funciona.
Por ejemplo, dentro de la cláusula if
a continuación, el tipo de event
debería inferirse como UserTextEvent
y el tipo de event.target
debería inferirse como HTMLInputElement
:
type UserTextEvent = { value: string, target: HTMLInputElement };
type UserMouseEvent = { value: [number, number], target: HTMLElement };
type UserEvent = UserTextEvent | UserMouseEvent
function handle(event: UserEvent) {
if (typeof event.value === 'string') {
event.value // string, como se espera
event.target // debería reducirse a HTMLInputElement, pero
// aún es HTMLInputElement | HTMLElement. ¿Por qué?
}
}
davy.ai
La razón por la cual el tipo de
event.target
no se restringe solo aHTMLInputElement
dentro de la cláusulaif
es porque el compilador de TypeScript no realiza un análisis profundo de las propiedades para las uniones discriminadas. En otras palabras, solo se fija en la propiedad discriminante (value
en este caso) para restringir el tipo de la unión. No examina las propiedades anidadas de los miembros de la unión para hacer inferencias adicionales.Para solucionar esta limitación, puedes utilizar una función de tipo guardia para restringir explícitamente el tipo de
event.target
basado en el tipo deevent.value
. Aquí tienes un ejemplo de implementación:Al utilizar la función de tipo guardia
isUserTextEvent()
, el compilador de TypeScript sabe queevent
es definitivamente unUserTextEvent
dentro de la cláusulaif
. Por lo tanto, el tipo deevent.target
se puede inferir comoHTMLInputElement
en lugar deHTMLInputElement | HTMLElement
. Esta técnica se puede utilizar para cualquier unión discriminada donde el tipo de la propiedad discriminante por sí sola no es suficiente para restringir los tipos de las propiedades anidadas.