Bug: `DeepReadonly<T>` and `DeepWritable<T>` are not exact inverses if `T` is a type parameter
polyipseity opened this issue · comments
Versions
package | version |
---|---|
typescript |
5.0.4 |
ts-essentials |
9.3.2 |
Repro Code
import type { DeepReadonly, DeepWritable } from 'ts-essentials'
declare function read<T>(value: DeepReadonly<T>): void
declare function write<T>(value: DeepWritable<T>): void
type ReadonlyWritable<T> = DeepReadonly<DeepWritable<T>>
type WriteableReadonly<T> = DeepWritable<DeepReadonly<T>>
function readwrite<T>(rw: ReadonlyWritable<T>, wr: WriteableReadonly<T>) {
read<T>(rw)
write<T>(wr)
}
TypeScript Playground
Expected Result
DeepReadonly<DeepWritable<T>>
should be assignable to DeepReadonly<T>
and DeepWritable<DeepReadonly<T>>
should be assignable to DeepWritable<T>
.
Actual Result
The above are not actually assignable if T
depends on any type parameter (if T
is fully concrete then it works as expected). It would be nice if this also works for type parameters.
However, I am not sure if this is even possible in TypeScript (the type system might not be powerful enough, or that checking for such type equality with a free parameter is undecidable), and it might be more work than what it is worth.
A more practical workaround I am using right now is manually doing the conversion using a overloaded function, which you may be interested in:
export function simplifyType<T>(value: DeepWritable<DeepReadonly<T>>): DeepWritable<T>
export function simplifyType<T>(value: DeepReadonly<DeepWritable<T>>): DeepReadonly<T>
export function simplifyType<T>(value: T): T { return value }
Hey @polyipseity
Thank you for reporting this issue
I won' be available to look at it until beginning of June, I will come back to you once I have some time
Apologies in advance
Hey @polyipseity
I don't have any ideas about how to fix it yet. To keep assignability, we have to add T & <do something else with T>
which breaks both utility types
If you have any suggestions, I'm open to experiments. Have you seen it working on other type libraries?