0

I'm trying to create a type that will make any array/object deeply read-only. So far I created this type:

  type DeepReadonly<G> = G extends Array<infer U> ?
  ReadonlyArray<DeepReadonly<U>> :
  (G extends object ? Readonly<{[p in keyof G]: DeepReadonly<G[p]>}> : G);

But I have a problem when the generic type is any. In this case, DeepReadonly becomes a union type of all possibilities in the conditional type above including any. Which ends up with not read-only type.

For example:

let x: DeepReadonly<any> = 1;
x = 2; // no error

Is there a type like 'any' that can be defined as readonly in case it's array/object? Is it possible to achieve what I want in the first place with TypeScript?

Thanks in advance!

2 Answers2

0

In your case, the variable can be assigned to because you used a let. Using a let will always be assignable—that’s what it is for.

let x: ...

// This will never be an error for a valid type value, as "let" by definition means that it is assignable.
x = ...

To make it so you can’t assign to x, you first have to use a const.

That said, to your original question, if you pass any as the type parameter, you are expressly dipping out of the type system and allowing anything to be assigned to the variable. There is no type definition you can use that will cause any to be readonly any, which is not a concept that quite makes sense.

Eric Ferreira
  • 1,811
  • 18
  • 20
0
export  type ReadonlyDeep<T> = {
    readonly [P in keyof T]: ReadonlyDeep<T[P]>;
};
sab
  • 4,352
  • 7
  • 36
  • 60