Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
Allow symbols in Brand (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti authored Mar 26, 2023
1 parent d87464b commit 25cbf46
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-impalas-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/schema": minor
---

Allow symbols in Brand
2 changes: 1 addition & 1 deletion docs/modules/Schema.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ Schema<A> + B -> Schema<A & Brand<B>>
**Signature**

```ts
export declare const brand: <B extends string, A>(
export declare const brand: <B extends string | symbol, A>(
brand: B,
options?: AnnotationOptions<A> | undefined
) => <I>(self: Schema<I, A>) => BrandSchema<I, any>
Expand Down
19 changes: 19 additions & 0 deletions dtslint/ts4.7/Brand.errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as S from "@effect/schema/Schema";
import { pipe } from "@effect/data/Function";

const Int1 = Symbol.for('Int')
const Int2 = Symbol.for('Int')

const schema1 = pipe(S.number, S.int(), S.brand(Int1))
const schema2 = pipe(S.number, S.int(), S.brand(Int2))

type A1 = S.To<typeof schema1>
type A2 = S.To<typeof schema2>

declare const a1: A1
declare const a2: A2
declare const f: (int: A1) => void

f(a1)
// $ExpectError
f(a2)
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@
"zod": "^3.21.4"
},
"dependencies": {
"@effect/data": "~0.5.0",
"@effect/io": "^0.10.0",
"@effect/data": "^0.6.0",
"@effect/io": "^0.12.2",
"fast-check": "^3.7.1"
},
"pnpm": {
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ export interface BrandSchema<From, To extends Brand<any>>
* @category combinators
* @since 1.0.0
*/
export const brand = <B extends string, A>(
export const brand = <B extends string | symbol, A>(
brand: B,
options?: AnnotationOptions<A>
) =>
Expand Down Expand Up @@ -1217,7 +1217,7 @@ export const BrandTypeId = "@effect/schema/BrandTypeId"
* @category combinators
* @since 1.0.0
*/
export const fromBrand = <C extends Brand<string>>(
export const fromBrand = <C extends Brand<string | symbol>>(
constructor: Brand.Constructor<C>,
options?: AnnotationOptions<Brand.Unbranded<C>>
) =>
Expand Down
11 changes: 11 additions & 0 deletions test/Decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,17 @@ describe.concurrent("Decoder", () => {
)
})

it("brand/symbol decoding", async () => {
const Int = Symbol.for("Int")
const schema = pipe(S.string, S.numberFromString, S.int(), S.brand(Int))
await Util.expectParseSuccess(schema, "1", 1 as any)
await Util.expectParseFailure(
schema,
null,
`Expected string, actual null`
)
})

it("tuple. empty", async () => {
const schema = S.tuple()
await Util.expectParseSuccess(schema, [])
Expand Down
20 changes: 20 additions & 0 deletions test/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ describe.concurrent("Schema", () => {
})
})

it("brand/symbol annotations", () => {
const A = Symbol.for("A")
const B = Symbol.for("B")
const Branded = pipe(
S.string,
S.numberFromString,
S.int(),
S.brand(A),
S.brand(B, {
description: "a B brand"
})
)
expect(Branded.ast.annotations).toEqual({
[AST.TypeAnnotationId]: "@effect/schema/IntTypeId",
[AST.BrandAnnotationId]: [A, B],
[AST.DescriptionAnnotationId]: "a B brand",
[AST.JSONSchemaAnnotationId]: { type: "integer" }
})
})

it("brand/ ()", () => {
const Int = pipe(S.string, S.numberFromString, S.int(), S.brand("Int"))
expect(Int(1)).toEqual(1)
Expand Down

0 comments on commit 25cbf46

Please sign in to comment.