Home > Mobile >  How to recursively replace typescript primitives with a parameterized type
How to recursively replace typescript primitives with a parameterized type

Time:09-29

type or interface could both work.

interface example {
  s: string;
  o: {
    t: string;
    arrn: number[];
    arr: {
      u: string;
    }[];
};

Would transform to

interface transformed {
  s: {
    onChange: (v: string) => void;
  };
  o: {
    t: {
      onChange: (v: string) => void;
    };
    arrn: {
      onChange: (v: number) => void;
    }[];
    arr: {
      u: {
        onChange: (v: number) => void;
      };
    }[];
};

Is this possible?

What is the direction to do something like this?

CodePudding user response:

type Transform<T> = T extends object
  // T is an object (including an array), so transform each property
  ? {[K in keyof T]: Transform<T[K]>}
  // T is a primitive, so do the transformation
  : {onchange: (v: T) => void};

type transformed = Transform<example>

This works as expected for tuples and arrays as well:

// {onchange: (v: string) => void}[]
type ArrayTest = Transform<string[]>;
// readonly {onchange: (v: string) => void}[]
type ReadonlyArrayTest = Transform<readonly string[]>;
/* [
  {onchange: (v: string) => void},
  {onchange: (v: number) => void},
  ...{onchange: (v: boolean) => void}[],
] */
type TupleTest = Transform<[string, number, ...boolean[]]>;

Playground link

CodePudding user response:

I think the following type satisfies what you describe:

interface example {
  s: string;
  o: {
    t: string;
    arrn: number[];
    arr: {
      u: string;
    }[];
  };
}

type ReplacePrimitives<T> = T extends Record<any, any>
  ? { [K in keyof T]: ReplacePrimitives<T[K]> }
  : { onChange: (value: T) => void };

type transformed = ReplacePrimitives<example>;

It recursively replaces all primitive values with the onChange object you describe, leaving records and array structures in place.

  • Related