05821-medium-maptypes

Back

type MapTypes<T, R extends { mapFrom: any; mapTo: any }> = {
  [k in keyof T]: T[k] extends R['mapFrom'] ? (R extends { mapFrom: T[k] } ? R['mapTo'] : never) : T[k];
};

Solution by wendao-liu #35087

type MapTypes<T, R extends { mapFrom: unknown, mapTo: unknown }> = {
  [K in keyof T]: T[K] extends R['mapFrom'] ? R extends { mapFrom: T[K] } ? R['mapTo'] : never : T[K]
}

Solution by dimitriiy #34582

//  R 可能是联合类型,因此需要多一步 R extends {mapFrom: T[K]} 的判断
type MapTypes<T, R extends { mapFrom: any, mapTo: any }> = {
  [P in keyof T]: T[P] extends R['mapFrom'] ? R extends { mapFrom: T[P] } ? R['mapTo'] : never : T[P]
}

Solution by ouzexi #34100

// your answers

type MapTypes<T extends Record<string, any>, R extends { mapFrom: any; mapTo: any }> = {
	[P in keyof T]: T[P] extends R["mapFrom"]
		? R extends {}
			? Equal<T[P], R["mapFrom"]> extends true
				? R["mapTo"]
				: never
			: never
		: T[P];
};

Solution by pea-sys #33115

type MapTypes<T extends Record<string, unknown>, R extends { mapFrom: unknown; mapTo: unknown }> = {
	[P in keyof T]: T[P] extends R["mapFrom"]
		? R extends {}
			? Equal<T[P], R["mapFrom"]> extends true
				? R["mapTo"]
				: never
			: never
		: T[P];
};

Solution by gasmg #32350

type MapType = {
  mapFrom: unknown,
  mapTo: unknown
}

type MapTo<T extends MapType, V> =  T extends { mapFrom: V } ? T['mapTo'] : never

type MapTypes<T extends Record<string | number | symbol, unknown>, R extends MapType> = {
  [K in keyof T]: T[K] extends R['mapFrom'] ? MapTo<R, T[K]> : T[K]
}

Solution by zhangqiangzgz #30209

type getMapTo<U, T, K> = {
  [Obj in U as Obj["mapFrom"] extends T ? K : never]: Obj["mapTo"];
}[K];

type MapTypes<T, R> = {
  [K in keyof T]: unknown extends getMapTo<R, T[K], K>
    ? T[K]
    : getMapTo<R, T[K], K>;
};

Solution by idebbarh #29882

type MapTypes<T, R extends { mapFrom: any; mapTo: any }> = {
  [K in keyof T]: T[K] extends R["mapFrom"]
    ? R extends R
      ? T[K] extends R["mapFrom"]
        ? R["mapTo"]
        : never
      : never
    : T[K];
};

Solution by DoubleWoodLin #28783

// your answers
interface IMap { mapFrom: any, mapTo: any };
type FormatVal<R extends IMap, V> = R extends R ? V extends R['mapFrom'] ? R['mapTo'] : V : never

type MapTypes<T, R extends IMap> = [R['mapTo']] extends [never] ? T
: {
  [K in keyof T]: Equal<FormatVal<R, T[K]>, T[K]> extends true ? T[K] : Exclude<FormatVal<R, T[K]>, T[K]>
};

Solution by ixiaolong2023 #27861

type MapTypes<T, R extends { mapFrom: any; mapTo: any }> = { 
  [K in keyof T]: T[K] extends R['mapFrom'] 
    ? R extends { mapFrom: T[K] }
      ? R['mapTo']
      : never
    : T[K]
}

Solution by mrdulin #27515

type MapTypes<T, R extends { mapFrom: any, mapTo: any }> =
  { [K in keyof T]: T[K] extends R['mapFrom'] ? R extends { mapFrom: T[K] } ? R["mapTo"] : never : T[K] }

Solution by smileboyi #27148

// 第一版 如果R 是联合类型,那么R['mapTo']是无法获取类型的,导致测试用例无法通过
// type MapTypes<T, R extends { mapFrom: any, mapTo: any }> = {
   // [key in keyof T] : T[key] extends R['mapFrom'] ? R['mapTo'] : T[key]
// }

// 第二版 利用联合类型 在条件判断中的distributive(分发)特性
type MapTypes<T, R extends { mapFrom: any, mapTo: any }> = {
  [key in keyof T] : T[key] extends R['mapFrom'] 
  ? R extends { mapFrom: T[key] } 
    ? R['mapTo'] : never 
  : T[key]
}

Solution by liuk123456789 #26256

// your answers
interface mapConvert {
  mapFrom: unknown,
  mapTo: unknown,
}

type MapTypes<T extends Object, R extends mapConvert > = {
  [K in keyof T]: 
    T[K] extends R['mapFrom'] 
    ? R extends {mapFrom: T[K]} 
      ? R['mapTo'] 
      : never 
    : T[K]
}

Solution by kiki-zjq #25710

type MapTypes<T, R extends {mapFrom: unknown, mapTo: unknown} = {
  [K in keyof T]: T[K] extends R['mapFrom'] ? R extends {mapFrom: T[K]} ? R['mapTo'] : never : T[K]
};

Solution by guckin #25472

type MapTypes<T extends Record<string, unknown>, R extends { mapFrom: unknown; mapTo: unknown }> = {
  [P in keyof T]: T[P] extends R['mapFrom']
    ? R extends { mapFrom: T[P] }
      ? R['mapTo']
      : never
    : T[P]
}

Solution by sromic #24847

// your answers
type MapTypes<T extends { [x: PropertyKey]: any }, R extends { mapFrom: any, mapTo: any }> =
  {
    [P in keyof T]: T[P] extends R[`mapFrom`] ?
    (
      R extends { mapFrom: T[P], mapTo: infer V } ? V : never
    )
    : T[P]
  };

Solution by studymachiney #24398

type MapTypes<T extends object, R extends { mapFrom: any, mapTo: any }> =
  {
    [P in keyof T]: T[P] extends R[`mapFrom`] ?
    (
      R extends { mapFrom: T[P], mapTo: infer V } ? V : never //进一步收窄
    )
    : T[P]
  };

Solution by E-uler #23997

type Map = { mapFrom: any; mapTo: any }
type ApplyMap<A, M extends Map> = M extends { mapFrom: A; mapTo: infer T } 
  ? T
  : M extends Map ? never : never;

type MapTypes<T, M extends Map> = {
  [K in keyof T]: ApplyMap<T[K], M> extends infer Mapped ? 
  [Mapped] extends [never] ? T[K] : Mapped
  : never
}

Solution by flavianh #23398

// 最开始的思路
type MapTypes<
  T extends Record<string, unknown>,
  R extends { mapFrom: unknown; mapTo: unknown },
> = R extends { mapFrom: infer From; mapTo: infer To }
  ? {
    [K in keyof T]: T[K] extends From ? To : T[K];
  }
  : never;

// 但是这样会导致联合类型的 R 展开,导致部分 case 无法通过
// 例如:
type A = {
  date: Date;
} | {
  date: null;
};

// 正确答案:让联合类型在对象里面展开

type MapTypes<
  T extends Record<string, unknown>,
  R extends { mapFrom: unknown; mapTo: unknown },
> = {
  [K in keyof T]: T[K] extends R['mapFrom']
    ? // 防止获取的 R['mapTo'] 类型错误
      R extends { mapFrom: T[K]; mapTo: infer To }
      ? To
      : never
    : T[K];
};

Solution by nia3y #23366

-->

type Dist<T, R> = R extends { mapFrom: unknown; mapTo: unknown }
  ? T extends R["mapFrom"]
    ? R["mapTo"]
    : never
  : never;

type Default<T, D> = [T] extends [never] ? D: T;

type MapTypes<T, R> = {
  [K in keyof T]: Default<Dist<T[K], R>, T[K]>;
};

Solution by coderyoo1 #22964

// your answers
type MapTypes<T extends Record<string, any>, R extends { mapFrom: any; mapTo: any }> = {
  [Key in keyof T]: T[Key] extends R['mapFrom']
    ? R extends { mapFrom: T[Key] }
      ? R['mapTo']
      : never
    : T[Key]
}

Solution by jxhhdx #22747

type MapTypes<T extends Record<string, any>, R extends { mapFrom: any; mapTo: any }> = {
  [Key in keyof T]: T[Key] extends R['mapFrom']
    ? R extends { mapFrom: T[Key] }
      ? R['mapTo']
      : never
    : T[Key]
}

// for the first check iterate by each property in T, afterwards iterate T[Key] by each R to check every {mapFrom..., mapTo} union structure

Solution by misterhomer1992 #22528

type MapTypes<
  T extends Record<string, unknown>,
  R extends { mapFrom: unknown, mapTo: unknown },
> = {
  [Key in keyof T]: T[Key] extends R['mapFrom']
    ? R extends { mapFrom: T[Key], mapTo: unknown }
      ? R['mapTo']
      : never
    : T[Key]
}

Solution by drylint #22071

type MapTypes<T, R extends { mapFrom: unknown }> = {
  [Key in keyof T]: T[Key] extends R["mapFrom"]
    ? R extends { mapTo: infer To }
      ? T[Key] extends R["mapFrom"] ? To : never
      : T[Key]
    : T[Key];
};

Solution by gaac510 #21206

type MapTypes<
  Type extends object,
  PropertyTypeMapper extends { mapFrom: unknown; mapTo: unknown }
> = {
  [Key in keyof Type]: (
    PropertyTypeMapper extends PropertyTypeMapper
      ? Type[Key] extends PropertyTypeMapper['mapFrom']
        ? PropertyTypeMapper['mapTo']
        : never
      : never
  ) extends infer MappedPropertyType
    ? [MappedPropertyType] extends [never]
      ? Type[Key]
      : MappedPropertyType
    : never;
};

Solution by yevhenpavliuk #21204

  type MapTypes<T, R extends { mapFrom: unknown; mapTo: unknown }> =
     {
        [key in keyof T]: T[key] extends R['mapFrom'] ? R['mapTo'] : T[key];
      }

Solution by angelise7 #20652

type MapTypes<T, R extends { mapFrom: any; mapTo: any },X = {
  [P in keyof T]: R extends R ? R["mapFrom"] extends  T[P] ? R["mapTo"] : never : never; 
}> = {
  [P in keyof X]:[X[P]] extends [never] ? P extends keyof T ? T[P] :  never :X[P];
};

type MapTypes<T, R extends { mapFrom: any; mapTo: any }> = {
  [P in keyof T]: (R extends R ? R["mapFrom"] extends  T[P] ? R["mapTo"] : never :never)  extends 
  infer X ? [X] extends [never] ? T[P] : X :never;
};

Solution by so11y #20471

// your answers

type MapTypes<T, R extends { readonly mapFrom: unknown, readonly mapTo: unknown }> = {
  [key in keyof T]: T[key] extends R['mapFrom'] ? Extract<R, { mapFrom: T[key] }>['mapTo'] : T[key]
}

Solution by Quanzhitong #20391

type Mapper = {
  mapFrom: unknown;
  mapTo: unknown
}

type MapTypes<T extends Record<PropertyKey, any>, R extends Mapper> = {
  [P in keyof T]: (R extends {mapFrom: T[P]} ? R['mapTo']: never) extends infer K
    ? [K] extends [never]
      ? T[P]
      : K
    : never
}

Learned:

(...) extends infer K let us create a temp variable K and allow us to use it multiple times latter

Solution by zhaoyao91 #19714

type MapTypes<T extends object, R extends Record<'mapFrom' | 'mapTo', any>> = {
  [K in keyof T]: T[K] extends R['mapFrom'] ? (R extends { mapFrom: T[K] } ? R['mapTo'] : never) : T[K];
};

Solution by CaoXueLiang #18672