simple-runtypes icon indicating copy to clipboard operation
simple-runtypes copied to clipboard

Chain custom runtimes with other runtypes

Open sbley opened this issue 1 year ago • 2 comments

How can I use custom runtimes (that transform a value into another type) with other runtypes?

For example, if I wanted to verify an optional BigInt type:

st.optional(bigIntRuntype()) // 🛑

This would fail because bigIntRuntype() returns bigint whereas st.optional() expects Runtype<unknown> as a parameter.

With the built-in runtypes, it works. Example:

st.optional(stringAsInteger()) // ✅

sbley avatar Jul 22 '24 13:07 sbley

The trick is to wrap your bigIntRuntype function with the runtype constructor.

Using plain functions that throw errors is too slow. So simple-runtypes internal return type is a wrapped value. runtype allows you to construct functions that follow that pattern.

Have you tried the example from the README? It shows how to implement a basic BigInt runtype.

hoeck avatar Jul 22 '24 14:07 hoeck

Got it, thank you.

In case it helps anyone, here is a runtype for a base64 check:

export const base64 = <T>(rt: Runtype<T>): Runtype<T> =>
  runtype((v) => {
    // check if base64 encoded string and decode
    const base64Check = use(base64Runtype, v);

    if (base64Check.ok) {
      const internalRuntypeCheck = use(rt, base64Check.result);
      if (internalRuntypeCheck.ok) {
        return internalRuntypeCheck.result;
      }

      return internalRuntypeCheck.error;
    }

    return createError('Invalid base64 string');
  });

sbley avatar Jul 23 '24 09:07 sbley