Closed
Description
TypeScript Version: 3.1.1+
Search Terms: DeepReadonly
Code
export type Primitive = string | number | boolean | undefined | null | Function | symbol;
export type DeepReadonly<T> =
T extends [infer A] ? DeepReadonlyObject<[A]> :
T extends [infer A, infer B] ? DeepReadonlyObject<[A, B]> :
T extends [infer A, infer B, infer C] ? DeepReadonlyObject<[A, B, C]> :
T extends [infer A, infer B, infer C, infer D] ? DeepReadonlyObject<[A, B, C, D]> :
T extends [infer A, infer B, infer C, infer D, infer E] ? DeepReadonlyObject<[A, B, C, D, E]> :
T extends [infer A, infer B, infer C, infer D, infer E, infer F] ? DeepReadonlyObject<[A, B, C, D, E, F]> :
T extends [infer A, infer B, infer C, infer D, infer E, infer F, infer G] ? DeepReadonlyObject<[A, B, C, D, E, F, G]> :
T extends Map<infer U, infer V> ? ReadonlyMap<DeepReadonlyObject<U>, DeepReadonlyObject<V>> :
T extends Set<infer U> ? ReadonlySet<DeepReadonlyObject<U>> :
T extends Promise<infer U> ? Promise<DeepReadonlyObject<U>> :
T extends Primitive ? T :
T extends (infer A)[] ? DeepReadonlyArray<A> :
DeepReadonlyObject<T>;
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
type DeepReadonlyObject<T> = { readonly [P in keyof T]: DeepReadonly<T[P]> }
Expected behavior:
This used to work as of typescript 3.0.1
Actual behavior:
In typescript 3.1.1 a new error is thrown saying that the type is cyclical
In typescript 3.2+ the above error, instead ends up casting the type as any
Playground Link:
Here's a gist with tests for the type
https://gist.github.com/masterkidan/7322752f569b1bba53e0426266768623