Creating Schema Combinators for Complex Transformations in TypeScript
I have found myself in need for a couple of schema combinators that simplify handling complex schema transformations in a declarative way. What do you think about my approach? Are there downsides? (ignore the custom dual definition)
composeExtendcomposeExtendexport declare namespace composeExtend {
export type DataFirst = <A1, I1, R1, A2, I2, R2>(
fromSchema: Schema.Schema<A1, I1, R1>,
extension: Schema.Schema<A2, I2, R2>
) => Schema.transform<
Schema.Schema<A1, I1, R1>,
Schema.extend<Schema.Schema<A1, I1, R1>, Schema.Schema<A2, I2, R2>>
>
export type DataLast = <A2, I2, R2>(
extension: Schema.Schema<A2, I2, R2>
) => <A1, I1, R1>(
fromSchema: Schema.Schema<A1, I1, R1>
) => Schema.transform<
Schema.Schema<A1, I1, R1>,
Schema.extend<Schema.Schema<A1, I1, R1>, Schema.Schema<A2, I2, R2>>
>
export type Signature = DataLast & DataFirst
}
export const composeExtend: composeExtend.Signature = dual<composeExtend.DataFirst, composeExtend.Signature>(
2,
(fromSchema, extension) => Schema.compose(fromSchema, Schema.extend(fromSchema, extension), { strict: false })
)export declare namespace composeExtend {
export type DataFirst = <A1, I1, R1, A2, I2, R2>(
fromSchema: Schema.Schema<A1, I1, R1>,
extension: Schema.Schema<A2, I2, R2>
) => Schema.transform<
Schema.Schema<A1, I1, R1>,
Schema.extend<Schema.Schema<A1, I1, R1>, Schema.Schema<A2, I2, R2>>
>
export type DataLast = <A2, I2, R2>(
extension: Schema.Schema<A2, I2, R2>
) => <A1, I1, R1>(
fromSchema: Schema.Schema<A1, I1, R1>
) => Schema.transform<
Schema.Schema<A1, I1, R1>,
Schema.extend<Schema.Schema<A1, I1, R1>, Schema.Schema<A2, I2, R2>>
>
export type Signature = DataLast & DataFirst
}
export const composeExtend: composeExtend.Signature = dual<composeExtend.DataFirst, composeExtend.Signature>(
2,
(fromSchema, extension) => Schema.compose(fromSchema, Schema.extend(fromSchema, extension), { strict: false })
)excludeexcludeexport declare namespace exclude {
export type DataFirst = <A1, I1, R1, A2, I2, R2>(
exclude: Schema.Schema<A1, I1, R1>,
fromSchema: Schema.Schema<A2, Exclude<I2, A1>, R2>
) => Schema.transform<
Schema.Union<[Schema.Schema<A1, I1, R1>, Schema.Schema<A2, Exclude<I2, A1>, R2>]>,
Schema.Schema<A2, Exclude<I2, A1>, R2>
>
export type DataLast = <A1, I1, R1>(
exclude: Schema.Schema<A1, I1, R1>
) => <A2, I2, R2>(
fromSchema: Schema.Schema<A2, Exclude<I2, A1>, R2>
) => Schema.transform<
Schema.Union<[Schema.Schema<A1, I1, R1>, Schema.Schema<A2, Exclude<I2, A1>, R2>]>,
Schema.Schema<A2, Exclude<I2, A1>, R2>
>
export type Signature = DataLast & DataFirst
}export declare namespace exclude {
export type DataFirst = <A1, I1, R1, A2, I2, R2>(
exclude: Schema.Schema<A1, I1, R1>,
fromSchema: Schema.Schema<A2, Exclude<I2, A1>, R2>
) => Schema.transform<
Schema.Union<[Schema.Schema<A1, I1, R1>, Schema.Schema<A2, Exclude<I2, A1>, R2>]>,
Schema.Schema<A2, Exclude<I2, A1>, R2>
>
export type DataLast = <A1, I1, R1>(
exclude: Schema.Schema<A1, I1, R1>
) => <A2, I2, R2>(
fromSchema: Schema.Schema<A2, Exclude<I2, A1>, R2>
) => Schema.transform<
Schema.Union<[Schema.Schema<A1, I1, R1>, Schema.Schema<A2, Exclude<I2, A1>, R2>]>,
Schema.Schema<A2, Exclude<I2, A1>, R2>
>
export type Signature = DataLast & DataFirst
}