UNPKG

io-ts-extra

Version:

Adds pattern matching, optional properties, and several other helpers and types, to io-ts.

58 lines 2.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.narrow = void 0; const io_ts_1 = require("io-ts"); const Either_1 = require("fp-ts/lib/Either"); const chain = Either_1.either.chain; /** * Like io-ts's refinement type but: * 1. Not deprecated (see https://github.com/gcanti/io-ts/issues/373) * 2. Passes in `Context` to the predicate argument, so you can check parent key names etc. * 3. Optionally allows returning another io-ts codec instead of a boolean for better error messages. * * @example * const CloudResources = narrow( * t.type({ * database: t.type({username: t.string, password: t.string}), * service: t.type({dbConnectionString: t.string}), * }), * ({database}) => t.type({ * service: t.type({dbConnectionString: t.literal(`${database.username}:${database.password}`)}), * }) * ) * * const valid = CloudResources.decode({ * database: {username: 'user', password: 'pass'}, * service: {dbConnectionString: 'user:pass'}, * }) * // returns a `Right` * * const invalid = CloudResources.decode({ * database: {username: 'user', password: 'pass'}, * service: {dbConnectionString: 'user:wrongpassword'}, * }) * // returns a `Left` - service.dbConnectionString expected "user:pass", but got "user:wrongpassword" */ const narrow = (codec, predicate, name = `(${codec.name} | ${io_ts_1.getFunctionName(predicate)})`) => { return new io_ts_1.RefinementType(name, (u) => { if (!codec.is(u)) { return false; } const refined = predicate(u, []); if (refined instanceof io_ts_1.Type) { return refined.is(u); } return refined; }, (i, c) => chain(codec.validate(i, c), a => { const refined = predicate(a, c); if (refined instanceof io_ts_1.Type) { return refined.validate(a, c); } if (refined) { return io_ts_1.success(a); } return io_ts_1.failure(a, c); }), codec.encode, codec, predicate); }; exports.narrow = narrow; //# sourceMappingURL=narrow.js.map