> [!thought] I always forget which is which. [Link, ](https://learn.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance)[Link](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#optional-variance-annotations-for-type-parameters) # ==CO==​variance allows ==outputs== to be more ==specific==: - read-only data types are normally covariant. - Variable of type `Iterable<? extends Base>` can hold `Iterable<Child>` . - In [[Java]], `extends` is the keyword for covariance. - In [[TypeScript]], `out` is the keyword for covariance. - https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations - "In a structural type system like TypeScript’s, covariance and contravariance are naturally emergent behaviors that follow from the definition of types." - "Because variance is a naturally emergent property of structural types, TypeScript automatically _infers_ the variance of every generic type. **In extremely rare cases** involving certain kinds of circular types, this measurement can be inaccurate. If this happens, you can add a variance annotation to a type parameter to force a particular variance:" # ==CONTRA==variance allows ==inputs== to be more ==general==: - write-only data types are normally contravariant. - Variable of type `Setter<? super Child>` can hold `Setter<Base>` . - In [[Java]], `super` is the keyword for contravariance. - In [[TypeScript]], `in` is the keyword for contravariance. - `readonly` is a keyword, but it isn't used too often. # With generic arrays Typed Arrays, (say, `T[]`), if you need to read and write to it, must be **invariant**. - Read only arrays are covariant. - Write-only arrays are contravariant.