1
\$\begingroup\$

I recently started TS. I was looking for feedback on my below function (for example maybe it can be written in shorter way). Let's assume we still use the reduce function.

The function description:

Write a function which takes object, and another object which contains validators for each of the fields of the main object. Then the function should apply the validators and return result, which is also an object containing either error messages or not for relevant fields.

Function:

type ResultType<T> = { [k in keyof T]: string | null };
function validate<T extends {}>(
  target: T,
  validators: { [k in keyof T]: (value: T[k]) => string | null }
): ResultType<T> {
  return Object.keys(target).reduce((accum, current) => {
    accum[current as keyof ResultType<T>] = validators[
      current as keyof typeof validators
    ](target[current as keyof T]);
    return accum;
  }, {} as ResultType<T>);
}

console.log(
  validate(
    { name: "John", age: 6 },
    {
      name: (p) => (!p ? "String should not be empty" : null),
      age: (p) => (p < 10 ? "Small age" : null),
    }
  )
);

Output:

{
  "name": null,
  "age": "Small age"
} 
\$\endgroup\$
1
  • \$\begingroup\$ You really need that reduce()? I think a much better implementation would be to use Object.entries and Object.fromEntries. Check out this video \$\endgroup\$
    – Jacob
    Nov 1, 2022 at 19:55

1 Answer 1

0
\$\begingroup\$

This looks good to me! You could create another type for the Validators, as you have for the ResultType, ie.

type ResultType<T> = { [k in keyof T]: string | null };
type Validators<T> = { [k in keyof T]: (value: T[k]) => string | null }

function validate<T extends Record<string, unknown>> (
  target: T,
  validators: Validators<T>
): ResultType<T> {

And add a line space before the function... but it is clear and concise to my eye.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.