Skip to content

Add a pedantic array variance option #40939

Closed
@cntkillme

Description

@cntkillme

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions