← Усі задачіTypeScript · Senior

DeepReadonly<T>

Вбудований Readonly<T> захищає лише перший рівень: config.server.port = 1 компілюється. Напишіть DeepReadonly<T>, що робить readonly всі поля на будь-якій глибині, зокрема масиви та їхні елементи.

Функції лишаються як є, а примітиви (string, number...) повертаються без змін.

Тести (5)

Тести типів перевіряє компілятор TypeScript у режимі strict. Expect<Equal<A, B>> проходить, коли типи збігаються точно, а // @ts-expect-error - коли наступний рядок не компілюється. Перший запуск завантажує компілятор, тож триває кілька секунд.

  1. типи
    type Config = { server: { port: number; tls: { cert: string } } };
    type _ = Expect<Equal<DeepReadonly<Config>, { readonly server: { readonly port: number; readonly tls: { readonly cert: string } } }>>;
  2. типи
    type State = { items: { id: number }[] };
    type _ = Expect<Equal<DeepReadonly<State>, { readonly items: readonly { readonly id: number }[] }>>;
  3. типи
    type Api = { load: (id: number) => string };
    type _ = Expect<Equal<DeepReadonly<Api>, { readonly load: (id: number) => string }>>;
  4. типи
    type _ = Expect<Equal<DeepReadonly<string>, string>>;
  5. типи
    const c = {} as DeepReadonly<{ a: { b: number } }>;
    // @ts-expect-error - nested fields are readonly too
    c.a.b = 2;