Home > Enterprise >  Make type deeply writable
Make type deeply writable

Time:09-07

Is it possible to transform a typescript object type deeply writable, but also remove readonly type operator from array types?

Similar to this, but - as I mentioned - also remove readonly from array types.

// if initial type is:
interface InitialType {
  readonly field: string;
  readonly array: readonly { readonly arraySubfield: string; }[];
  readonly obj: {
    readonly objSubfield1: string;
    readonly objSubfield2: readonly string[];
  };
}

// then the result type would be:
interface ResultType {
  field: string;
  array: { arraySubfield: string }[];
  obj: {
    objSubfield1: string;
    objSubfield2: string[];
  };
}

// achieved by doing this:
type ResultType = Writable<InitialType>;

CodePudding user response:

Here ya go, a deep writable type that handles way too many things:

type Writable<T> =
    // check for things that are objects but don't need changing
    T extends ((...args: any[]) => any) | Date | RegExp
        ? T
        : T extends ReadonlyMap<infer K, infer V> // maps
            ? Map<Writable<K>, Writable<V>> // make key and values writable
            : T extends ReadonlySet<infer U> // sets
                ? Set<Writable<U>> // make elements writable
                : T extends ReadonlyArray<unknown> // is an array or tuple?
                    ? `${bigint}` extends `${keyof T & any}` // is tuple
                        ? { -readonly [K in keyof T]: Writable<T[K]> }
                        : Writable<T[number]>[] // is regular array
                    : T extends object // is regular object
                        ? { -readonly [K in keyof T]: Writable<T[K]> }
                        : T; // is primitive or literal value

Essentially it's this:

type Writable<T> = T extends object ? { -readonly [K in keyof T]: Writable<T[K]> } : T;

but it handles a lot more things correctly. Things like (and only) arrays dates, functions, regex, maps, sets, tuples, readonly maps, and readonly sets.

Playground

  • Related