I'm looking to create a function that generates instances of objects. These objects will only have one field, but the name and type of the value associated with it should be set dynamically (preferably using constants).
I've tried experimenting with generics and restrictions, but I'm having trouble understanding them.
// Objective: Create an object with a property that is a 1-element array
function factory<TContainer, TElement>(key: string, element: TElement): TContainer {
return {[key]: [element]};
}
// How I want to use it
// Given a type
type T1 = {
key1: number[];
};
// Instead of
const e1a: T1 = { key1: [1]};
const e1b: T1 = { key1: [1, 2]};
const e1c: T1 = { key1: []};
// I want to write
const e1z: T1 = factory<T1, number>('key1', 999); // e1z === {key1: [999]};
const e2z: T2 = factory<T2, string>('key2', 'z'); // e2z === {key2: ['z']};
// Moreover, I also want to use it without explicit types
const onthefly:{onthefly:string[]} = factory<{onthefly:string[]}, string>('onthefly', 'onthefly'); // onthefly === {onthefly: ['onthefly']};
// Even better if the compiler could infer the types without explicitly specifying them
const magic = factory('magic', 3); // magic:{magic:number[]} === {magic:[3]}
But I keep getting errors like:
Type '{ [x: string]: TElement[]; }' is not assignable to type 'TContainer'.
'TContainer' could be instantiated with an arbitrary type which could be unrelated to '{ [x: string]: TElement[]; }'.