typescripttypescript-typings

How to create an object type based on keys/values of a const object in TypeScript?


I need to define a type based on a config object (anObject), which will be used in my code.

I wrote something like the following,

const anObject = {
  foo: ["a", "b", "c"],
  bar: ["d", "e", "f"],
} as const;

type aType =
  | { key: ""; value: [] }
  | { key: "foo"; value: ("a" | "b" | "c")[] }
  | { key: "bar"; value: ("d" | "e" | "f")[] };

const a: aType = { key: "", value: [] }; // No error
const b: aType = { key: "foo"; value: ["a", "b"] }; // No error
const c: aType = { key: "bar"; value: ["e", "f"] }; // No error

How to declare aType dynamically in TypeScript?


Solution

  • It worth using union here:

    const anObject = {
        foo: ["a", "b", "c"],
        bar: ["d", "e", "f"],
    } as const;
    
    type AnObject = typeof anObject;
    
    type Values<T> = T[keyof T]
    
    type AType = {
        [P in keyof AnObject]: {
            key: P,
            value: Array<AnObject[P][number]>
        }
    }
    
    type Default = { key: ""; value: [] }
    
    type Result = Values<AType> | Default
    
    const foo: Result = { key: "", value: [] }; // ok
    const bar: Result = { key: "bar", value: ["d"] } // ok
    

    Feel free to add any new keys to anObject. You don't need to make updates anywhere else

    Please keep in mind, as @T.J Crowder said, there is no order in value property. TS will allow different combinations of value: [d,e] | [e, d] | [d].

    If you want it in same order, just use this line: value: AnObject[P] in AType helper