Any isn’t required. The go-to example of unsoundness is the Cat[] ref that you alias as an Animal[], append a Dog to, then map over the original ref calling ‘meow()’ on each entry.
JavaScript arrays are heterogeneous and TypeScript permits covariance here because the underlying language lacks any mechanism to freeze any shared references to the array to prevent it.
TypeScript could restrict this to be through an operation that creates a new array (e.g.: via .slice()), however that would impose a performance deficit versus vanilla JavaScript. It's not acceptable to the TypeScript project to impose a cost on what would, in JS, just be array assignment or argument passing.
It would be a neat idea to allow a "strictCovariance" mode to allow covariance only with readonly arrays - I think that might solve the issue? i.e.: I can cast "Cat[]" to a "readonly Animal[]", but not to a mutable "Animal[]".