I'm having issues with a mapped type converting to a union-type array rather than a tuple type.
I'm seeing an error that indicates that fn expects a signature of
'(...values: (string | boolean)[]) => void' vs my preferred
'(a: string, b: boolean) => void'
It's likely my misunderstanding of this change, but is there something missing that would type RawValues<T> to a tuple rather than a union-type array to allow me to strongly type the arguments of the fn I pass in?
Thanks!
type ValueType<T> = { value: T; };
type RawValue<T> = T extends ValueType<infer U> ? U : never;
type RawValues<T> = {
[P in keyof T]: RawValue<T[P]>;
};
function extractAndRun<T extends ValueType<any>[]>(values: T, fn: (...values: RawValues<T>) => void): RawValues<T> {
const rawValues = values.map((val) => val.value) as RawValues<T>;
fn(...rawValues);
return rawValues;
}
const result = extractAndRun(
[{value: 'string'}, {value: true}],
// PROBLEM IS HERE. See error message in code block below.
(a: string, b: boolean) => {
console.log(a);
console.log(b);
});
console.log(result); // ['string', true]
Argument of type '(a: string, b: boolean) => void' is not assignable to parameter of type '(...values: (string | boolean)[]) => void'.
Types of parameters 'a' and 'values' are incompatible.
Type 'string | boolean' is not assignable to type 'string'.
Type 'boolean' is not assignable to type 'string'.
'b' is declared but its value is never read.