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