I am currently working on a feature where I need to create a function that takes an interface as input and automatically determines the return types based on the 'key' provided in the options object passed to the function.
Here is an example of what I'm aiming for:
const stringKeyValue = createKeyValueMapped<{a: string, b: number}>({
key: "a", // key: "a"
value: "hi", // value: string
transform: (value) => value + ' more text', // (value: string) => string
});
stringKeyValue.key; // key: 'a'
stringKeyValue.value; // value: string
The problem is that in my current implementation, the key
type ends up being 'a' | 'b'
, and the value type becomes 'string' | 'number'
.
This is the existing code snippet causing issues:
export type KeyValue<
Inputs,
Key extends keyof Inputs,
Value = Inputs[Key]
> = {
key: Key;
value: Value;
transform: (value: Value) => Value;
};
type KeyValuesMapped<Inputs> = {
[Key in keyof Inputs]: KeyValue<Inputs, Key>;
}[keyof Inputs];
const createKeyValueMapped = <Inputs,>({ key, value }: KeyValuesMapped<Inputs>) =>
({
key,
value,
});
I attempted to solve this by creating a type for KeyValue
, encapsulating the options within a function, and specifying the return types. However, this approach completely broke the mapping functionality.
You can explore a comprehensive example using this Link to Playground