| 3726 | * @since 4.0.0 |
| 3727 | */ |
| 3728 | export function extendTo<S extends Struct<Struct.Fields>, const Fields extends Struct.Fields>( |
| 3729 | /** The new fields to add */ |
| 3730 | fields: Fields, |
| 3731 | /** A function per field to derive its value from the original input */ |
| 3732 | derive: { readonly [K in keyof Fields]: (s: S["Type"]) => Option_.Option<Fields[K]["Type"]> } |
| 3733 | ) { |
| 3734 | return ( |
| 3735 | self: S |
| 3736 | ): decodeTo<Struct<Simplify<{ [K in keyof S["fields"]]: toType<S["fields"][K]> } & Fields>>, S> => { |
| 3737 | const f = Record_.map(self.fields, toType) |
| 3738 | const to = Struct({ ...f, ...fields }) |
| 3739 | return self.pipe(decodeTo( |
| 3740 | to, |
| 3741 | SchemaTransformation.transform({ |
| 3742 | decode: (input) => { |
| 3743 | const out: any = { ...input } |
| 3744 | for (const k in fields) { |
| 3745 | const f = derive[k] |
| 3746 | const o = f(input) |
| 3747 | if (Option_.isSome(o)) { |
| 3748 | InternalRecord.assignProperty(out, k, o.value) |
| 3749 | } |
| 3750 | } |
| 3751 | return out |
| 3752 | }, |
| 3753 | encode: (input) => { |
| 3754 | const out = { ...input } |
| 3755 | for (const k in fields) { |
| 3756 | delete out[k] |
| 3757 | } |
| 3758 | return out |
| 3759 | } |
| 3760 | }) |
| 3761 | )) as any |
| 3762 | } |
| 3763 | } |
| 3764 | |
| 3765 | /** |
| 3766 | * Namespace for `Record` type utilities. |