简体   繁体   中英

Is it possible to create union key value type from object type?

For example I have object type

type FooBar = {
  foo: number,
  bar: string
}

and I want to create this type

{key: "foo", value: number} | {key: "bar", value: string}

I can create

{key: keyof FooBar}

and

{value: FooBar[keyof FooBar]}

But I want to combine them somehow.

You can do this with a mapped type. Map each key to a {key: <keyname>, value: <keytype>} type, then build the union of all those using keyof :

type FooBar = {
  foo: number,
  bar: string
}

type KV<T> = {[K in keyof T]: {key: K, value: T[K]}}[keyof T];

declare const test: KV<FooBar>;
// `test` has type: {key: "foo", value: number} | {key: "bar", value: string}

Inspired by CRice 's answer , the following snippet supports nested objects as well:

type ObjectDeepValues<OBJ_T> = {
    [K in keyof OBJ_T]: OBJ_T[K] extends Record<PropertyKey, unknown>
        ? ObjectDeepValues<OBJ_T[K]>
        : OBJ_T[K]
}[keyof OBJ_T];

const obj = {
    x: 5,
    b: true,
    nestedObj: {
        a: "hi",
    },
} as const;

type t1 = ObjectDeepValues<typeof obj>; // true | 5 | "hi"

( TS Playground )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM