# TSR0501: '…' is not assignable to '…': mutable '…' is invariant in sound mode, so writes through '…' could break '…'. Use '…' if it is only read.

> A mutable array, tuple, Map or Set is used as one with a wider element type, so writes could break it. Use the readonly type if it is only read.

## What it means

In sound files, `T[]`, `Array<T>`, mutable tuples, `Map`, `Set`, `WeakMap` and `WeakSet` are invariant: `Dog[]` is not assignable to `Animal[]`, because code holding the `Animal[]` could push a `Cat` into it. The readonly forms (`readonly T[]`, `ReadonlyMap`, `ReadonlySet`, `Iterable<T>`) stay covariant. It's reported where tsc reports assignability errors; `{3}` names the readonly form.

## Example

```ts
// string[] to (string | number)[]: a number could be pushed into the string array.
const strings: string[] = ["a"];
const mixed: (string | number)[] = strings; // @expect TSR0501
export const n: number = mixed.length;
```

## How to fix

- If the target is only read, make it readonly: `readonly Animal[]`, `ReadonlyMap<string, Animal>`.
- Make function parameters that never write `readonly` (the planned quick fix does this).
- Copy when ownership moves: `[...dogs]`, `new Map(dogMap)`.

Sound mode is defined in [design record 0007](https://github.com/Webb-Ventures/typescript-rust/blob/main/docs/design/0007-sound-mode.md) (accepted 2026-10-15).

Source: https://ts-r.dev/errors/TSR0501/
