29650-medium-extracttoobject

Back

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]]
  }

Playground

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 = { [K in keyof T] : T[K] }

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