Búsqueda de sitios web

javascript - Propiedades de objetos TypeScript dinámicas a partir de argumentos de función


Tengo una función que recibe un número n de argumentos y genera un nuevo objeto que contiene un mapa clave-valor de los argumentos a un hash único.

¿Hay alguna manera de que TypeScript infiera dinámicamente las claves del objeto devuelto a partir de los argumentos de la función?

Ejemplo,

Función CreateActionType que genera el diccionario:

function createActionType<K extends {} | void>(...type: string[]): Readonly<{ [key: string]: string }> {
    const actions = {};

    type.forEach((item: string) => {
        actions[item] = `${item}/${generateUniqueId()}`;
    });

    return Object.freeze(actions);
};

Usando createActionType:

interface ActionTypes {
    MY_ACTION_1, 
    MY_ACTION_2
}

const action = createActionType<ActionTypes>("MY_ACTION_1", "MY_ACTION_2");
/*
 * action contains { MY_ACTION_1: "MY_ACTION_1/0", MY_ACTION_2: "MY_ACTION_2/1" }
 */
action.MY_ACTION_1; // returns "MY_ACTION_1/0"

Me gustaría eliminar la duplicación y simplemente llamar a createActionType así:

const action = createActionType("MY_ACTION_1", "MY_ACTION_2");
action.MY_ACTION_1;  // Intellisense will be able to infer the properties 
                     // MY_ACTION_1 and MY_ACTION_2 from action

Respuesta #1

Encontré una solución usando la palabra clave in

function createActionType<K extends string>(...type: K[]): { [P in K]: string } {
    const actions = {};

    type.forEach((item: string) => {
        actions[item] = `${item}/${generateUniqueId()}`;
    });

    return Object.freeze(actions) as Readonly<{ [P in K]: string }>;
};

Usando K como los argumentos de la función, podemos asignar el valor de retorno para que sea un objeto con claves que contengan literales de cadena definidas por K.

Lectura adicional: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#mapped-types