Given the following code, I expect it to compile without errors:
type Immutable<T> = T extends object
? { readonly [K in keyof T]: Immutable<T[K]>; }
: T;
function foo<T>(t: T): Immutable<T> {
return t;
}
However tsc
outputs a quite unhelpful error message:
Type 'T' is not assignable to type 'Immutable<T>'.
The error disappears when the conditional is removed:
- type Immutable<T> = T extends object
- ? { readonly [K in keyof T]: Immutable<T[K]>; }
- : T;
+ type Immutable<T> = { readonly [K in keyof T]: Immutable<T[K]>; };
function foo<T> (t: T): Immutable<T> {
return t;
}
Why does the original error occur? Why the conditional type here breaks the variance T extends Immutable<T>
? I want to have a solution that won't use as T
casts whatsoever.
Meta:
$ npx tsc --version
Version 4.1.3
Unfortunately, changing the definition of Immutable
is complicated (it requires a PR to the upstream repo).
The original problem was when using immer
library (here is the definition if Immutable<T>
), and as far as I can tell, the authors of immer
haven't found the solution and thus propose a workaround with castImmutable<T>(): Immutable<T>
function