Skip to content

Commit

Permalink
Schema: add compose overloads to enable a subtyping relationship in…
Browse files Browse the repository at this point in the history
… both di… (#2531)
  • Loading branch information
gcanti committed Apr 16, 2024
1 parent 78b767c commit e542371
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-chicken-trade.md
@@ -0,0 +1,5 @@
---
"@effect/schema": patch
---

add `compose` overloads to enable a subtyping relationship in both directions between `C` and `B`.
46 changes: 31 additions & 15 deletions packages/schema/dtslint/Schema.ts
Expand Up @@ -1241,7 +1241,7 @@ pipe(
)

// ---------------------------------------------
// Compose
// compose
// ---------------------------------------------

// A -> B -> C
Expand All @@ -1252,37 +1252,53 @@ S.compose(S.split(","), S.Array(S.NumberFromString))
// $ExpectType Schema<readonly number[], string, never>
S.split(",").pipe(S.compose(S.Array(S.NumberFromString)))

// decoding (strict: false)
// $ExpectType Schema<readonly number[], string, never>
S.compose(S.split(","), S.Array(S.NumberFromString), { strict: true })

// // $ExpectType Schema<readonly number[], string, never>
// S.split(",").pipe(S.compose(S.Array(S.NumberFromString), { strict: true }))

// @ts-expect-error
S.compose(S.String, S.Number)

// @ts-expect-error
S.String.pipe(S.compose(S.Number))

// A -> B+, B -> C

// $ExpectType Schema<number, string | null, never>
S.compose(S.Union(S.Null, S.String), S.NumberFromString, { strict: false })
S.compose(S.Union(S.Null, S.String), S.NumberFromString)

// $ExpectType Schema<number, string | null, never>
S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString, { strict: false }))
S.compose(S.Union(S.Null, S.String), S.NumberFromString, { strict: false })

// decoding (strict: true)
// // $ExpectType Schema<number, string | null, never>
// S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString))

// @ts-expect-error
S.compose(S.Union(S.Null, S.String), S.NumberFromString)
// $ExpectType Schema<number, string | null, never>
S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString, { strict: false }))

// @ts-expect-error
S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString))
// A -> B, B+ -> C

// encoding (strict: false)
// $ExpectType Schema<number | null, string, never>
S.compose(S.NumberFromString, S.Union(S.Null, S.Number))

// $ExpectType Schema<number | null, string, never>
S.compose(S.NumberFromString, S.Union(S.Null, S.Number), { strict: false })

// // $ExpectType Schema<number | null, string, never>
// S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number)))

// $ExpectType Schema<number | null, string, never>
S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number), { strict: false }))

// encoding (strict: true)
// A -> B -> C -> D

// @ts-expect-error
S.compose(S.NumberFromString, S.Union(S.Null, S.Number))
// $ExpectType Schema<number, string, never>
S.compose(S.String, S.Number, { strict: false })

// @ts-expect-error
S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number)))
// $ExpectType Schema<number, string, never>
S.String.pipe(S.compose(S.Number, { strict: false }))

// ---------------------------------------------
// FromBrand
Expand Down
14 changes: 11 additions & 3 deletions packages/schema/src/Schema.ts
Expand Up @@ -2531,7 +2531,7 @@ export const extend: {
export const compose: {
<C, B, R2>(
to: Schema<C, B, R2>
): <A, R1>(from: Schema<B, A, R1>, options?: { readonly strict: true }) => Schema<C, A, R1 | R2>
): <A, R1>(from: Schema<B, A, R1>) => Schema<C, A, R1 | R2>
<D, C, R2>(
to: Schema<D, C, R2>,
options: { readonly strict: false }
Expand All @@ -2541,14 +2541,22 @@ export const compose: {
to: Schema<C, B, R2>,
options?: { readonly strict: true }
): Schema<C, A, R1 | R2>
<A, B, R1, D, C, R2>(
<B, A, R1, D, C extends B, R2>(
from: Schema<B, A, R1>,
to: Schema<D, C, R2>
): Schema<D, A, R1 | R2>
<B extends C, A, R1, D, C, R2>(
from: Schema<B, A, R1>,
to: Schema<D, C, R2>
): Schema<D, A, R1 | R2>
<B, A, R1, D, C, R2>(
from: Schema<B, A, R1>,
to: Schema<D, C, R2>,
options: { readonly strict: false }
): Schema<D, A, R1 | R2>
} = dual(
(args) => isSchema(args[1]),
<A, B, R1, D, C, R2>(from: Schema<A, B, R1>, to: Schema<D, C, R2>): Schema<D, A, R1 | R2> =>
<B, A, R1, D, C, R2>(from: Schema<B, A, R1>, to: Schema<D, C, R2>): Schema<D, A, R1 | R2> =>
make(AST.compose(from.ast, to.ast))
)

Expand Down

0 comments on commit e542371

Please sign in to comment.