API

Codec.assert

Asserts that a given runtime value matches the codec's static type. That is, it's a value that would be valid to return from the Codec.parse method.

For example:

import * as ft from "funtypes";
import * as s from 'funtypes-schemas';

export const UserCodec = ft.Object({
  id: ft.Number,
  name: ft.String,
  dateOfBirth: s.ParsedDateTimeString(),
});
// => ft.Codec<{ id: number; name: string; dateOfBirth: Date }>

// ✅ Valid so no error is thrown
UserCodec.assert({
  id: 1,
  name: "Forbes Lindesay",
  dateOfBirth: new Date("1970-01-01T00:00:00.000Z")
});

// 🚨 Invalid: id should be a number, but here we've
//    passed a string instead.
assert.throws(() => {
  UserCodec.assert({
    id: "42",
    name: "Forbes Lindesay",
    dateOfBirth: new Date("1970-01-01T00:00:00.000Z")
  });
});

// 🚨 Invalid: dateOfBirth is a string, which would
//    be ok if the value was serialized, but the
//    Codec.assert function tests if the value
//    matches the **parsed** schema
assert.throws(() => {
  UserCodec.assert({
    id: 1,
    name: "Forbes Lindesay",
    dateOfBirth: "1970-01-01T00:00:00.000Z"
  });
});

Note that TypeScript can tell that the type is constrained by the Codec.assert call:

/**
 * TypeScript can infer that this function returns
 * a value of type `string`. The function will
 * throw an error if you give it anything other than
 * a valid User object.
 */
function dangerouslyGetUserName(user: unknown) {
  UserCodec.assert(user);
  return user.name;
}

// ✅ Valid so no error is thrown and the name is returned
assert.deepEqual(
  dangerouslyGetUserName(
    {
      id: 1,
      name: "Forbes Lindesay",
      dateOfBirth: new Date("1970-01-01T00:00:00.000Z")
    }
  ),
  "Forbes Lindesay",
);

// 🚨 Invalid: even though this object has a "name" prop,
//    It is not a valid User object, so UserCodec.assert
//    will throw an error.
assert.throws(() => {
  dangerouslyGetUserName({
    name: "Forbes Lindesay",
  });
});
Previous
Codec