Home > database >  Typescript flattens array types to their element type not working inside Mapped Types
Typescript flattens array types to their element type not working inside Mapped Types

Time:10-14

I have User type like below

interface IUserMongo {
  name: string;
  age: number;
  address: string[];
  nested: {
    name: string;
    sayYes: boolean;
    rrr: 1;
  };
}

I want to derive the following type

interface IUserMongo {
  name: number;
  age: number;
  address:number;
  nested: {
    name: number;
    sayYes: number;
    rrr: number;
  };
}

code is working except for arrays.

error: Type 'number' is not assignable to type 'number[]'

ts playground link

interface IUserMongo {
  name: string;
  age: number;
  address: string[];
  nested: {
    name: string;
    sayYes: boolean;
    rrr: 1;
  };
}

type IUserProject<T, N = number> = {
  [K in keyof T]: T[K] extends object ? IUserProject<T[K], N> : N;
};

const projection: IUserProject<IUserMongo> = {
  name: 1,
  age: 1,
  address: 1,
  nested: {
    sayYes: 1,
    name: 1,
    rrr: 1,
  },
};

const user: IUserMongo = {
  name: 'sdg',
  age: 1,
  address: ['gfg'],
  nested: {
    sayYes: true,
    name: 'rrr',
    rrr: 1,
  },
};

// this is the behavior i want
interface MultiContainer {
  Item1: string[];
  Item2: number[];
}

type SingleContainer = { [P in keyof MultiContainer]: number };

const tt: SingleContainer = {

    Item1: 1,
    Item2: 1,
};

CodePudding user response:

Check if it's an array:

type IUserProject<T, N = number> = {
  [K in keyof T]: T[K] extends object ? T[K] extends ReadonlyArray<unknown> ? N : IUserProject<T[K], N> : N;
};

Works now

  • Related