I have one function
export const mappingResult = <
const M extends Record<keyof T, string>,
T extends Record<string, null | string | number | boolean>
>(
schema: M,
input: T
) => {
return Object.keys(input).reduce(
(acc, key) => {
const val = schema[key];
const inputValue = input[key];
if (val) {
acc[val] = inputValue;
}
return acc;
},
{} as { [K: string]: null | string | number | boolean }
);
};
How can I change the type that from the last [K: string]
that string, to refer the type of M extends Record<keyof T, string>
that string
?
I’m trying to use
{} as { [K in keyof T as M[K]]: null | string | number | boolean }
but acc[val]
says
No index signature with a parameter of type 'string' was found on type '{ [K in keyof T as M[K]]: string | number | boolean | null; }
3
Okay, so this is not a direct answer, but the comment section is too hard to format neatly so I will post my suggestion as an answer.
I have not tested the following code, but it demonstrates an overall idea that might help.
I suggest changing your approach to reduce the noisiness of all the typings.
so for instance
export type SignificantValue = string | number | boolean | null
// Using object notation over using a Record type often makes
// type design easier
// The best time to use the Record type is usually
// For complex objects and classes that behave like an object
// but are not plain objects, such as a proxy object
export type MergableObject = {
[key: string]: SignificantValue
}
export function pickInputFieldsBySchema<TSchema extends MergableObject, TInput extends MergableObject, TFused extends MergableObject = Partial<TInput>> (schema: TSchema, input: TInput): TFused {
const result: TFused = {}
Object.entries(input).forEach(([k,v])=>{
if(schema[k as keyof TSchema]){
result[k as keyof TInput]=v
}
})
return result
}
If you like, try out code similar to this and see if you get any type errors, and then I can continue helping
Lastly, it is a bit unclear if you are using your code in a dynamic or static way. If you schema is static (i.e. as const
), then you have the opportunity to give stronger typing, but if your code is dynamic where schema is changing dynamically (for instance, maybe you are designing a custom ORM solution or form validation code?), then you really don’t have as much strong typing that is inferrable, since the compiler does not know the shape of “schema” at compile time. You may need to further narrow data types in the location in which your function is actually used (call site), since the compiler wouldn’t know the shape of “schema” ahead of time.
Therefore, in my provided code, I added an optionalTFused
type if you want to narrow the result alter without using an as
clause.