UNPKG

ts-cast

Version:
38 lines (37 loc) 1.37 kB
import { createCaster } from '../engine'; import { isAnObj } from '../engine/guards'; import optional from '../engine/optional'; const transformStruct = (schema, ref) => { const fields = Object.entries(schema); return (value, context, reportError) => fields.reduce((target, [field, caster]) => Object.defineProperty(target, field, { enumerable: true, writable: true, configurable: true, value: caster(value[field], context ? `${context}.${String(field)}` : `${String(field)}`, reportError), }), Object.create(ref.caster.prototype)); }; const partial = (schema) => Object.keys(schema).reduce((newSchema, field) => { newSchema[field] = optional(schema[field]); return newSchema; }, Object.create(null)); export const struct = (schema, typeName = 'struct') => { const ref = {}; const caster = Object.defineProperties(createCaster(typeName, isAnObj, transformStruct(schema, ref)), { name: { value: typeName, }, partial: { enumerable: true, get: () => struct(partial(schema), `Partial<${typeName}>`), }, }); ref.caster = Object.defineProperty(caster, 'prototype', { enumerable: false, configurable: false, writable: true, value: { constructor: caster, }, }); return caster; };