DEV Community

Discussion on: Decoding JSON with Typescript

Collapse
 
0x80 profile image
Thijs Koerselman • Edited

This seems very similar to using a runtime schema validation library like Joi.

I've been using this helper function to typecheck API payloads. It returns the payload cast to the type it is supposed to be when the schema validates. If it doesn't validate the function throws an error with messages explaining what part of the schema failed to comply.

import * as Joi from "joi";

export function validatePayload<T>(payload: T, schema: Joi.AnySchema): T {
  const { error, value } = Joi.validate(payload, schema);

  if (error) {
    /**
     * Collect all of the Joi error messages and combine them in one
     * comma-separated string.
     */
    const errorMessages = error.details.map(errorItem => errorItem.message);
    throw new Error(errorMessages.join(","));
  }

  return value;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
joanllenas profile image
Joan Llenas Masó

Never used Joi before but it looks much more powerful (and heavy).
This library is just a few bytes, although it has all the basic pieces you need to build more Joi-ish stuff (I guess).
Something you can do with ts.data.json that I don't see in the Joi docs is mapping over a decoded value. For instance:

type User = {
    id: number,
    name: string,
    dateOfBirth: Date
}

JsonDecoder.object<User>(
    {
        id: JsonDecoder.number,
        name: JsonDecoder.string,
        dateOfBirth: JsonDecoder.string.map(stringDate => new Date(stringDate)),
    },
    'User'
);
Enter fullscreen mode Exit fullscreen mode

Very useful.

Thanks for pointing that out Thijs.
Cheers!

Collapse
 
0x80 profile image
Thijs Koerselman

Mapping seems useful indeed :)

I use Joi on the server so size is not an issue there. For the browser I use yup. Similar API but much smaller footprint.

Thread Thread
 
joanllenas profile image
Joan Llenas Masó

Interesting! smaller footprint but powerful too.
I might add an alternatives section in the ts.data.json docs.
Thanks!