so i'm working on a route and wanted to create a generic normalizer to use before saving my user into the database.
This is my normalizer function
import { INormalizer, IPayloadIndexer } from "../../interfaces/generics";
const normalizeRequestValues = <Type>(
payload: IPayloadIndexer<Type>,
normalizer: INormalizer
) => {
const normalizerKeys = Object.keys(normalizer);
const payloadEntries = Object.entries(payload);
payloadEntries.forEach(([key, value]) => {
if (normalizerKeys.includes(key)) {
payload[key] = normalizer[key](value as string);
}
});
};
export default normalizeRequestValues;
And on the payload[key] = normalizer[key](value as string); part of the code i'm receiving this error:
(parameter) payload: IPayloadIndexer<Type>
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IPayloadIndexer<Type>'.
No index signature with a parameter of type 'string' was found on type 'IPayloadIndexer<Type>'
INormalizer:
type INormalizer = {
[key: string]: (str: string) => string;
};
export default INormalizer;
IPayloadIndexer:
type IPayloadIndexer<Type> = {
[Property in keyof Type]: Type[Property];
};
export default IPayloadIndexer;
The function is being called first here:
import { IPayloadIndexer } from "../../interfaces/generics";
import { normalizeRequestValues } from "../generics";
import userNormalizer from "./userNormalizer.utils";
const normalizeUserRequestValues = <Type>(payload: IPayloadIndexer<Type>) => {
normalizeRequestValues<Type>(payload, userNormalizer);
};
export default normalizeUserRequestValues;
Using this normalizer:
import { INormalizer } from "../../interfaces/generics";
import { capitalizeText } from "../generics";
const userNormalizer: INormalizer = {
name: (name: string) => capitalizeText(name),
email: (email: string) => email.toLowerCase(),
};
export default userNormalizer;
And then it is called in my route service, here:
import { hash } from "bcrypt";
import { Request } from "express";
import { IServiceReturnMessage } from "../interfaces/generics";
import { IUser, IUserCreate } from "../interfaces/users";
import { UserRepository } from "../repositories";
import { normalizeUserRequestValues, serializeUser } from "../utils/user";
class UserService {
insertUser = async ({
validated,
}: Request): Promise<IServiceReturnMessage<IUser>> => {
validated.password = await hash(validated.password, 10);
normalizeUserRequestValues<IUserCreate>(validated as IUserCreate);
const user = await UserRepository.save({ ...validated });
const serializedUser = serializeUser(user);
return { statusCode: 201, message: serializedUser };
};
}
export default new UserService();
I could make it work by passing a //@ts-ignore above the line, but i really wanna learn how to do it, if any extra information is needeed i will gladly post in here.
Thanks in advance for any response!