Home > other >  Typescript: generic object with dynamic number of keys and values
Typescript: generic object with dynamic number of keys and values

Time:10-31

Currently, my code looks like this:

interface TestInterface<T extends string> {
    data: {
        [key in T]: () => void;
    }
}

const testCommand: TestInterface<"fun1"> = {
    data: {
        fun1: () => {
            // do something
        },
    }
};

testCommand.data.fun1();

I pass a string (in this example "fun1") as a generic to the testCommand function. In the data object, I can access this string/function "fun1".

My Question: Can I pass an array of strings as a generic to have a custom amount of functions in the data object (Maybe convert the data obj to an array)?

Example:

const testCommand: TestInterface<["fun1", "fun2", "fun3"]> = {
    data: {
        fun1: () => {
            // do something
        },
        fun2: () => {
            // do something
        },
        fun3: () => {
            // do something
        },
    }
};

or:

const testCommand: TestInterface<["fun1", "fun2", "fun3"]> = {
    data: [
        { name: "fun1", exec: () => {} },
        { name: "fun2", exec: () => {} },
        { name: "fun3", exec: () => {} },
    ]
};

CodePudding user response:

Instead of an array, you can just pass in a union of the string literal types you want to support; the resulting mapped type will contain all of the keys:

const testCommand: TestInterface<"fun1" | "fun2" | "fun3"> = {
    data: {
        fun1: () => {
            // do something
        },
        fun2: () => {
            // do something
        },
        fun3: () => {
            // do something
        },
    }
};

Indeed, this is very much like using the Record<K, V> utility type, where you pass in a union of key types for K and a value type for V, and get a type with properties of type V at all keys in K.

Playground link to code

  • Related