En esta sección, cubriremos el mecanismo de inferencia de tipos en TypeScript, particularmente dónde y cómo se infieren los tipos.
Tabla de contenidos
Conceptos básicos
Hay muchos lugares en TypeScript donde se usa la inferencia de tipo para proporcionar información de tipo cuando no hay una anotación de tipo explícita. Por ejemplo, en el siguiente código
let x = 3;
El tipo de la variable x
se infiere como type number
. Esta inferencia de tipo es al inicializar variables y elementos, al establecer valores predeterminados para los parámetros o al especificar el tipo de retorno de una función.
La inferencia de especies en la mayoría de los casos es directa. En las siguientes secciones, aprenderemos sobre algunos de los matices y pequeñas diferencias en el mecanismo de inferencia de especies.
Mejor tipo común
Cuando el tipo se deduce de varias expresiones, los tipos de esas expresiones se utilizan para calcular el mejor tipo común, por ejemplo:
let x = [0, 1, null];
Para deducir el tipo de x en el ejemplo anterior, debemos considerar el tipo de cada elemento de la matriz. Aquí tenemos dos opciones para el tipo de matriz: number
o null
. El algoritmo Best Common Type tiene en cuenta cada tipo de candidato y selecciona el tipo que coincide con el resto de los tipos de candidatos.
Debido a que la mejor especie común debe seleccionarse de la especie candidata, hay algunos casos en los que las especies comparten una estructura sin que una sola especie se considere una especie progenitora dominante (es decir, todas las especies heredan de ella) sobre el resto de las especies candidatas, por ejemplo:
let zoo = [new Rhino(), new Elephant(), new Snake()];
Idealmente, nos gustaría inferir el tipo de la variable zoo
a ser Animal[]
, pero dado que no hay ningún objeto de tipo Animal
explícito en la matriz, no inferimos el tipo de los elementos de la matriz. Para solucionar esto, se debe proporcionar el tipo cuando ninguno de los tipos de elementos sea dominante sobre el resto:
let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
Cuando no exista un tipo común dominante, la inferencia será el tipo de matriz de unión (Rhino | Elephant | Snake)[]
.
Tipo contextual
La inferencia de tipos también funciona al revés en algunos casos en TypeScript, y se llama escritura contextual. Los tipos contextuales son cuando se supone que el tipo de una expresión dada se conoce a partir de su ubicación, por ejemplo:
window.onmousedown = function(mouseEvent) { console.log(mouseEvent.button); // Error }
El código anterior arroja un error de tipo porque el verificador de tipos de TypeScript usa el tipo de función Window.onmousedown
para inferir tipo de la expresión de función en el lado derecho de la asignación. Así, se deduce el tipo del operando mouseEvent
.
Si esta función no estuviera en una posición en la que se pudieran usar los tipos contextuales, el tipo del parámetro mouseEvent
habría sido type any
y no habría ningún error. Si una expresión con un tipo contextual contiene información de tipo explícita, el tipo contextual se ignora. Si escribimos el ejemplo anterior de la siguiente manera:
window.onmousedown = function(mouseEvent: any) { console.log(mouseEvent.button); // No hay errores ahora }
Una expresión de función con una nota al pie de página de tipo de parámetro explícito anulará el tipo contextual. Una vez que haga eso, no habrá errores porque el tipo contextual ya no se aplica.
Los tipos contextuales funcionan en muchos casos. Las instancias comunes incluyen valores de parámetros pasados a llamadas de función, asignaciones del lado derecho, aserciones de tipo, elementos de objeto, literales de matriz y declaraciones de retorno. El tipo contextual también actúa como un filtro de tipo en el algoritmo Best Common Type, por ejemplo:
function createZoo(): Animal[] { return [new Rhino(), new Elephant(), new Snake()]; }
En este ejemplo, hay cuatro candidatos para el mejor algoritmo de tipo común Animal: Snake ,Rhino
y Elephant. De estos tipos candidatos, el algoritmo seleccionará porque todos los demás tipos heredan de Animal
.
Recursos del Artículo
- Iteradores y generadores en TypeScript
- Símbolo en TypeScript (Symbol)
- Tipos Avanzados en TypeScript
- Tipos de Compatibilidad en TypeScript
- Inferir Tipos en TypeScript
- Tipos Generalizados (Generics) en TypeScript
- Tipos Básicos de Datos en TypeScript
- Interfaces en TypeScript
- Declaración de Variables en TypeScript
- Funciones en TypeScript
- Categorías en TypeScript
- Introducción a TypeScript