Skip to content

Commit

Permalink
Remove Simplify from extend, pick, omit, pluck APIs, closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Jun 14, 2024
1 parent 07e12ec commit 980f916
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-eyes-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/schema": patch
---

Remove `Simplify` from `extend`, `pick`, `omit`, `pluck` APIs, closes #2989, #2990
2 changes: 1 addition & 1 deletion packages/schema/dtslint/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ S.Record(aContext, bContext)
// extend
// ---------------------------------------------

// $ExpectType Schema<{ readonly a: string; readonly b: number; readonly c: boolean; }, { readonly a: string; readonly b: number; readonly c: boolean; }, "aContext" | "bContext" | "cContext">
// $ExpectType Schema<{ readonly a: string; readonly b: number; } & { readonly c: boolean; }, { readonly a: string; readonly b: number; } & { readonly c: boolean; }, "aContext" | "bContext" | "cContext">
S.asSchema(S.Struct({ a: aContext, b: bContext }).pipe(S.extend(S.Struct({ c: cContext }))))

// $ExpectType extend<Struct<{ a: aContext; b: bContext; }>, Struct<{ c: cContext; }>>
Expand Down
16 changes: 8 additions & 8 deletions packages/schema/dtslint/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ S.Record(S.String.pipe(S.brand(Symbol.for("UserId"))), S.String)
// extend
// ---------------------------------------------

// $ExpectType Schema<{ readonly a: string; readonly b: string; readonly c: string; }, { readonly a: string; readonly b: string; readonly c: string; }, never>
// $ExpectType Schema<{ readonly a: string; readonly b: string; } & { readonly c: string; }, { readonly a: string; readonly b: string; } & { readonly c: string; }, never>
S.asSchema(pipe(
S.Struct({ a: S.String, b: S.String }),
S.extend(S.Struct({ c: S.String }))
Expand All @@ -1070,19 +1070,19 @@ pipe(
S.extend(S.Struct({ c: S.String }))
)

// $ExpectType Schema<{ readonly a: string; readonly b: string; readonly c: string; }, { readonly a: string; readonly b: string; readonly c: string; }, never>
// $ExpectType Schema<{ readonly a: string; readonly b: string; } & { readonly c: string; }, { readonly a: string; readonly b: string; } & { readonly c: string; }, never>
S.asSchema(S.extend(S.Struct({ a: S.String, b: S.String }), S.Struct({ c: S.String })))

// $ExpectType extend<Struct<{ a: typeof String$; b: typeof String$; }>, Struct<{ c: typeof String$; }>>
S.extend(S.Struct({ a: S.String, b: S.String }), S.Struct({ c: S.String }))

// $ExpectType Schema<{ readonly a: string; readonly b: number; } | { readonly a: string; readonly c: boolean; }, { readonly a: string; readonly b: number; } | { readonly a: string; readonly c: boolean; }, never>
// $ExpectType Schema<{ readonly a: string; } & ({ readonly b: number; } | { readonly c: boolean; }), { readonly a: string; } & ({ readonly b: number; } | { readonly c: boolean; }), never>
S.asSchema(S.extend(S.Struct({ a: S.String }), S.Union(S.Struct({ b: S.Number }), S.Struct({ c: S.Boolean }))))

// $ExpectType extend<Struct<{ a: typeof String$; }>, Union<[Struct<{ b: typeof Number$; }>, Struct<{ c: typeof Boolean$; }>]>>
S.extend(S.Struct({ a: S.String }), S.Union(S.Struct({ b: S.Number }), S.Struct({ c: S.Boolean })))

// $ExpectType Schema<{ readonly [x: string]: string; readonly a: string; readonly b: string; readonly c: string; }, { readonly [x: string]: string; readonly a: string; readonly b: string; readonly c: string; }, never>
// $ExpectType Schema<{ readonly a: string; readonly b: string; } & { readonly c: string; } & { readonly [x: string]: string; }, { readonly a: string; readonly b: string; } & { readonly c: string; } & { readonly [x: string]: string; }, never>
S.asSchema(pipe(
S.Struct({ a: S.String, b: S.String }),
S.extend(S.Struct({ c: S.String })),
Expand Down Expand Up @@ -1454,16 +1454,16 @@ S.asSchema(S.mutable(S.transform(S.Array(S.String), S.Array(S.String), { decode:
// $ExpectType mutable<transform<Array$<typeof String$>, Array$<typeof String$>>>
S.mutable(S.transform(S.Array(S.String), S.Array(S.String), { decode: identity, encode: identity }))

// $ExpectType Schema<{ a: string; b: number; }, { a: string; b: number; }, never>
// $ExpectType Schema<{ a: string; } & { b: number; }, { a: string; } & { b: number; }, never>
S.asSchema(S.extend(S.mutable(S.Struct({ a: S.String })), S.mutable(S.Struct({ b: S.Number }))))

// $ExpectType Schema<{ a: string; readonly b: number; }, { a: string; readonly b: number; }, never>
// $ExpectType Schema<{ a: string; } & { readonly b: number; }, { a: string; } & { readonly b: number; }, never>
S.asSchema(S.extend(S.mutable(S.Struct({ a: S.String })), S.Struct({ b: S.Number })))

// $ExpectType Schema<{ [x: string]: string; a: string; }, { [x: string]: string; a: string; }, never>
// $ExpectType Schema<{ a: string; } & { [x: string]: string; }, { a: string; } & { [x: string]: string; }, never>
S.asSchema(S.extend(S.mutable(S.Struct({ a: S.String })), S.mutable(S.Record(S.String, S.String))))

// $ExpectType Schema<{ readonly [x: string]: string; a: string; }, { readonly [x: string]: string; a: string; }, never>
// $ExpectType Schema<{ a: string; } & { readonly [x: string]: string; }, { a: string; } & { readonly [x: string]: string; }, never>
S.asSchema(S.extend(S.mutable(S.Struct({ a: S.String })), S.Record(S.String, S.String)))

// ---------------------------------------------
Expand Down
37 changes: 37 additions & 0 deletions packages/schema/dtslint/generic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Schema } from "@effect/schema"
import { Either } from "effect"

export const f1 = <A extends object, I extends object, R>(
resultSchema: Schema.Schema<A, I, R>
) => {
const left = Schema.Struct({
ok: Schema.Literal(false),
error: Schema.String
})
const right = <A, I, R>(
resultSchema: Schema.Schema<A, I, R>
) => Schema.extend(Schema.Struct({ ok: Schema.Literal(true) }), resultSchema)
const union = Schema.Union(left, right(resultSchema))
const out = Schema.transform(
union,
Schema.EitherFromSelf({ left: Schema.String, right: Schema.typeSchema(resultSchema) }),
{
decode: (u) => u.ok ? Either.right(u) : Either.left(u.error),
encode: (a) => ({ ok: true as const, ...a })
}
)
return out
}

type Model = { id: string } & Record<string, unknown>

export const f2 = <T extends Model>(schema: Schema.Schema<T>) => {
type Patch = Pick<T, "id"> & Partial<Omit<T, "id">>

const patch: Schema.Schema<Patch> = schema.pipe(
Schema.pick("id"),
Schema.extend(schema.pipe(Schema.omit("id"), Schema.partial()))
)

return patch
}
26 changes: 8 additions & 18 deletions packages/schema/src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2632,8 +2632,7 @@ export const Record = <K extends Schema.All, V extends Schema.All>(key: K, value
export const pick = <A, I, Keys extends ReadonlyArray<keyof A & keyof I>>(...keys: Keys) =>
<R>(
self: Schema<A, I, R>
): SchemaClass<Types.Simplify<Pick<A, Keys[number]>>, Types.Simplify<Pick<I, Keys[number]>>, R> =>
make(AST.pick(self.ast, keys))
): SchemaClass<Pick<A, Keys[number]>, Pick<I, Keys[number]>, R> => make(AST.pick(self.ast, keys))

/**
* @category struct transformations
Expand All @@ -2642,8 +2641,7 @@ export const pick = <A, I, Keys extends ReadonlyArray<keyof A & keyof I>>(...key
export const omit = <A, I, Keys extends ReadonlyArray<keyof A & keyof I>>(...keys: Keys) =>
<R>(
self: Schema<A, I, R>
): SchemaClass<Types.Simplify<Omit<A, Keys[number]>>, Types.Simplify<Omit<I, Keys[number]>>, R> =>
make(AST.omit(self.ast, keys))
): SchemaClass<Omit<A, Keys[number]>, Omit<I, Keys[number]>, R> => make(AST.omit(self.ast, keys))

/**
* Given a schema `Schema<A, I, R>` and a key `key: K`, this function extracts a specific field from the `A` type,
Expand Down Expand Up @@ -2686,7 +2684,7 @@ export const pluck: {
<A, I, R, K extends keyof A & keyof I>(
schema: Schema<A, I, R>,
key: K
): Schema<A[K], Types.Simplify<Pick<I, K>>, R> => {
): Schema<A[K], Pick<I, K>, R> => {
const ps = AST.getPropertyKeyIndexedAccess(AST.typeAST(schema.ast), key)
const value = make<A[K], A[K], R>(ps.isOptional ? AST.orUndefined(ps.type) : ps.type)
return transform(
Expand Down Expand Up @@ -2971,8 +2969,8 @@ const intersectUnionMembers = (
export interface extend<Self extends Schema.Any, That extends Schema.Any> extends
AnnotableClass<
extend<Self, That>,
Types.Simplify<Schema.Type<Self> & Schema.Type<That>>,
Types.Simplify<Schema.Encoded<Self> & Schema.Encoded<That>>,
Schema.Type<Self> & Schema.Type<That>,
Schema.Encoded<Self> & Schema.Encoded<That>,
Schema.Context<Self> | Schema.Context<That>
>
{}
Expand Down Expand Up @@ -3007,19 +3005,11 @@ export interface extend<Self extends Schema.Any, That extends Schema.Any> extend
* @since 0.67.0
*/
export const extend: {
<That extends Schema.Any>(
that: That
): <Self extends Schema.Any>(self: Self) => extend<Self, That>
<Self extends Schema.Any, That extends Schema.Any>(
self: Self,
that: That
): extend<Self, That>
<That extends Schema.Any>(that: That): <Self extends Schema.Any>(self: Self) => extend<Self, That>
<Self extends Schema.Any, That extends Schema.Any>(self: Self, that: That): extend<Self, That>
} = dual(
2,
<Self extends Schema.Any, That extends Schema.Any>(
self: Self,
that: That
) => make(extendAST(self.ast, that.ast, []))
<Self extends Schema.Any, That extends Schema.Any>(self: Self, that: That) => make(extendAST(self.ast, that.ast, []))
)

/**
Expand Down

0 comments on commit 980f916

Please sign in to comment.