Description
Search Terms
variance array
Suggestion
Currently, TypeScript allows assignment from D[]
to B[]
when D
is a subtype of B
.
Providing a configurable option to control if arrays are covariant (current behavior) vs invariant per project would allow for the user to take advantage of a more sound type system. Additionally, the assignment of a D[]
to a readonly B[]
is sound and should also be permitted when "pedantic array variance" is specified.
Use Cases
Having the type-checker treat arrays as invariant will allow the compiler to catch a class of issues that are currently not caught. Allowing covariant arrays can be a source of subtle bugs that are hard to track, and many projects do not benefit from having covariant arrays.
By allowing this to be configurable and having the default behavior assume covariant arrays, backwards compatibility is maintained but the user may also opt in to a more sound type system.
Examples
interface B { x: number, y: number }
interface D extends B { z: number }
const arr = new Array<D>();
const readonlyRef: ReadonlyArray<B> = arr; // okay
const ref: Array<B> = arr; // allowing this allows the next line
ref.push({ x: 1, y: 2 }); // oops!
const z = arr[0].z; // undefined (but the type system thinks it is a number)
With pedantic array variance, assignment of arr
to ref
would produce a diagnostic.
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.