type ExtractToObject<T extends Record<string, any>, U extends string> = {
[k in (keyof Omit<T, U> | keyof T[U])]: k extends keyof T ? T[k] : T[U][k]
}
Solution by wendao-liu #35157
type Merge<T, U> = {
[P in keyof (T & U)]: P extends keyof T ? T[P] : P extends keyof U ? U[P] : never;
};
type ExtractToObject<T, U extends keyof T> = Merge<
{
[P in Exclude<keyof T, U>]: P extends keyof T ? T[P] : never;
},
T[U]
>;
Solution by yukicountry #34390
type ExtractToObject<T, K extends keyof T> = Omit<
Omit<T, K> & T[K],
never
>
type Omit<T, K extends keyof T> = {
[Key in keyof T as Key extends K ? never : Key]: T[Key]
}
Solution by drylint #34171
// Omit<xx, never>是把交集转成对象,因为T可能为{}
type ExtractToObject<T extends object, U extends keyof T> = Omit<Omit<T, U> & T[U], never>
Solution by ouzexi #34170
// 你的答案
type MyMerge<T> = {
[P in keyof T]: T[P]
}
type ExtractToObject<T, U extends keyof T> = MyMerge<{
[P in keyof T as P extends U ? never : P]: T[P]
} & T[U]>
Solution by heyuelan #33912
type ExtractToObject<T, Prop extends keyof T> = Omit<Omit<T, Prop> & T[Prop], never>;
Solution by sunupupup #33489
type ExtractToObject<T, U extends keyof T> =
{
[K in Exclude<keyof T, U> | keyof T[U]]:
K extends keyof T
? T[K]
: T[U][K & keyof T[U]]
}
Solution by teamchong #32988
type Flatten<T> = {
[P in keyof T]: T[P]
}
type ExtractToObject<T extends object, U extends keyof T, Acc extends T = T[U]> = Flatten<{
[P in keyof T as Exclude<P, U>]: T[P]
} & Acc>
Solution by keyurparalkar #32874
当ExtractToObject的第二类型参数为联合类型时,发现很多答案通不过测试。
type test5 = {
id: "1";
prop1: { zoo: "2" };
prop2: { foo: "4" };
};
type testExpect5 = {
id: "1";
zoo: "2";
foo: "4";
};
Expect<Equal<ExtractToObject<test5, "prop1" | "prop2">, testExpect5>>
当为联合类型时,需要做更多处理
type ExtractToObject<T extends object, U extends keyof T> = Copy<
Omit<T, U> & (T[U] extends object ? IntesctionObject<T[U]> : {})
>;
type Copy<T> = {
[P in keyof T]: T[P];
};
type UnionToIntersection<T> = (
T extends any ? (a: (b: T) => void) => void : never
) extends (a: infer F) => void
? F
: never;
type UnionLast<T> = UnionToIntersection<T> extends (b: infer F) => void
? F
: never;
type IntesctionObject<T extends object> = [T] extends [never]
? {}
: UnionLast<T> & IntesctionObject<Exclude<T, UnionLast<T>>>;
Solution by Vampirelee #32593
type ExtractToObject<T, U extends keyof T> = {
[R in Exclude<keyof T, U> | keyof T[U]]: R extends keyof T[U]
? T[U][R]
: T[R & keyof T];
};
Solution by vangie #32200
type ExtractToObject<T, U> = U extends keyof T
? Omit<Omit<T, U> & T[U], never>
: T;
Solution by bigcreate #31192
type Merge<T, U, R = Omit<T, keyof U> & U> = {[K in keyof R]: R[K]};
type ExtractToObject<T extends object, U extends keyof T> = Merge<Omit<T, U>, T[U]>
Solution by milletlovemouse #31057
type ExtractToObject<T extends object, U extends string> = Omit<
Omit<T, U> & (U extends keyof T ? T[U] : {}),
never
>;
Solution by moonpoet #31051
type ExtractToObject<T, U extends keyof T> = Required<{
[key in keyof T as key extends U ? never : key]: T[key]
} & T[U]>;
On a similar note, using Omit:
type ExtractToObject<T, U extends keyof T> = Required<Omit<T & T[U], U>>;
Solution by BrunoLad #30998
type Prettify<T> = { [K in keyof T]: T[K] } & {}
type ExtractToObject<T, U extends keyof T> = Prettify<Omit<T, U> & T[U]>
Solution by DevilTea #30910
type Merge<F, S> = {
[key in keyof F | keyof S]: key extends keyof S ? S[key] : key extends keyof F ? F[key] : never
}
type ExtractToObject<T, U extends string> = U extends keyof T ? Merge<Omit<T, U>, T[U]> : T
Solution by moonshadow-miao #30826
type ExtractToObject<T, U extends keyof T> = Omit<Omit<T, U> & T[U], never>
Solution by dreamluo-plus #30704
type ExtractToObject<T extends Record<string, any>, U extends string> = { [K in (keyof Omit<T, U> | keyof T[U])]: K extends keyof T ? T[K] : T[U][K] }
Solution by zzjzz9266a #30642
// your answers
type ExtractToObject<T, K extends keyof T> = Combine<T[K] & Omit<T,K>>
type Combine<T> = {[K in keyof T]: T[K]};
Solution by janice143 #30224
type ExtractToObject<T extends object, U extends keyof T, _CombObj = Omit<T, U> & T[U]> = { [P in keyof _CombObj]: _CombObj[P] };
Solution by E-uler #29782
type Clone<T> = {
[K in keyof T]: T[K]
}
type ExtractToObject<T extends Record<string, any>, U extends keyof T> = Clone<Omit<T, U> & T[U]>
Solution by XkSuperCool #29763
type Merge<T> = {
[K in keyof T]:T[K]
}
type ExtractToObject<
T,
U extends keyof T
> =
Merge<
Omit<T,U>&T[U]
>
Solution by jiangshanmeta #29710
// your answers
type CopyMyObject
type ExtractToObject<T extends object, U extends keyof T> = CopyMyObject<{ [K in keyof T as K extends U ? never : K ]: T[K] } & T[U]>
Solution by kerolossamir165 #29704
type ExtractToObject<T, U extends keyof T> = Helper<Omit<T, U> & T[U]>
type Helper<T> = { [K in keyof T]: T[K] }
Solution by Sun79 #29680