Construcciones
Variance annotations
`in` y `out` declaran cómo se comporta un genérico cuando su parámetro cambia — algo que TypeScript deduce solo por su cuenta.
Qué es
Añadidas en la 4.7, y peculiares porque no cambian nada de lo que es legal: TypeScript ya infiere la varianza estructuralmente. Lo que aportan es velocidad e intención — el compilador puede saltarse la comparación estructural, y al lector se le dice sin rodeos si un `Box<string>` puede sustituir a un `Box<string | number>`. `out` significa que el parámetro se produce, `in` que se consume, `in out` ambas.
Ejemplos
Producer<string> extends Producer<string | number> ? true : false
→trueCovariante: algo que produce cadenas sirve allí donde se quiere algo que produzca cadenas o números.
Consumer<string | number> extends Consumer<string> ? true : false
→trueContravariante, y la dirección se invierte: algo que acepta más sirve allí donde se quiere algo que acepta menos.
Consumer<string> extends Consumer<string | number> ? true : false
→falseY al revés falla, que es justo para lo que está esa anotación.
Cada tipo resuelto de arriba lo imprimió TypeScript 5.9.3, no se escribió a mano.
Lo que no hace
- No legalizan nada que no lo fuera. Anota mal y el compilador rechaza la anotación, no el uso — comprueba tu afirmación contra la estructura.
- No hacen falta en la mayoría de los tipos. Recurre a ellas en genéricos recursivos grandes donde inferir la varianza es medibleme nte lento, no por estilo.
Conclusión
La varianza es la regla que decide cuándo un genérico puede sustituir a otro. Dependes de ella desde tu primer array; estas palabras clave solo te dejan decirlo en voz alta.