Skip to content

Commit 287c32c

Browse files
Add typeConstructor annotation for Schema (#5910)
1 parent 1b23741 commit 287c32c

File tree

9 files changed

+66
-3
lines changed

9 files changed

+66
-3
lines changed

.changeset/weak-tables-matter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
Add typeConstructor annotation for Schema

packages/ai/ai/src/Prompt.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,7 @@ export interface PromptEncoded {
13331333
export class PromptFromSelf extends Schema.declare(
13341334
(u) => isPrompt(u),
13351335
{
1336+
typeConstructor: { _tag: "effect/ai/Prompt" },
13361337
identifier: "PromptFromSelf",
13371338
description: "a Prompt instance",
13381339
arbitrary: (): Arbitrary.LazyArbitrary<Prompt> => (fc) =>

packages/cluster/src/Envelope.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export const EnvelopeFromSelf: Schema.Schema<
204204
Envelope.Any,
205205
Envelope.Any
206206
> = Schema.declare(isEnvelope, {
207+
typeConstructor: { _tag: "effect/cluster/Envelope" },
207208
identifier: "Envelope"
208209
})
209210

@@ -215,6 +216,7 @@ export const RequestFromSelf: Schema.Schema<
215216
Request.Any,
216217
Request.Any
217218
> = Schema.declare((u): u is Request.Any => isEnvelope(u) && u._tag === "Request", {
219+
typeConstructor: { _tag: "effect/cluster/Envelope.Request" },
218220
identifier: "Envelope"
219221
})
220222

packages/cluster/src/Reply.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,11 @@ export class Chunk<R extends Rpc.Any> extends Data.TaggedClass("Chunk")<{
192192
/**
193193
* @since 1.0.0
194194
*/
195-
static readonly schemaFromSelf: Schema.Schema<Chunk<never>> = Schema.declare((u): u is Chunk<never> =>
196-
isReply(u) && u._tag === "Chunk"
195+
static readonly schemaFromSelf: Schema.Schema<Chunk<never>> = Schema.declare(
196+
(u): u is Chunk<never> => isReply(u) && u._tag === "Chunk",
197+
{
198+
typeConstructor: { _tag: "effect/cluster/Reply.Chunk" }
199+
}
197200
)
198201

199202
/**

packages/effect/src/Schema.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,6 +4148,7 @@ export declare namespace Annotations {
41484148
* @since 3.10.0
41494149
*/
41504150
export interface Schema<A, TypeParameters extends ReadonlyArray<any> = readonly []> extends Doc<A> {
4151+
readonly typeConstructor?: AST.TypeConstructorAnnotation
41514152
readonly identifier?: AST.IdentifierAnnotation
41524153
readonly message?: AST.MessageAnnotation
41534154
readonly schemaId?: AST.SchemaIdAnnotation
@@ -4918,6 +4919,7 @@ export class ULID extends String$.pipe(
49184919
* @since 3.11.0
49194920
*/
49204921
export class URLFromSelf extends instanceOf(URL, {
4922+
typeConstructor: { _tag: "URL" },
49214923
identifier: "URLFromSelf",
49224924
arbitrary: (): LazyArbitrary<URL> => (fc) => fc.webUrl().map((s) => new URL(s)),
49234925
pretty: () => (url) => url.toString()
@@ -5850,6 +5852,7 @@ export const RedactedFromSelf = <Value extends Schema.Any>(value: Value): Redact
58505852
encode: (value) => redactedParse(ParseResult.encodeUnknown(value))
58515853
},
58525854
{
5855+
typeConstructor: { _tag: "effect/Redacted" },
58535856
description: "Redacted(<redacted>)",
58545857
pretty: () => () => "Redacted(<redacted>)",
58555858
arbitrary: redactedArbitrary,
@@ -5891,6 +5894,7 @@ export function Redacted<Value extends Schema.Any>(value: Value): Redacted<Value
58915894
export class DurationFromSelf extends declare(
58925895
duration_.isDuration,
58935896
{
5897+
typeConstructor: { _tag: "effect/Duration" },
58945898
identifier: "DurationFromSelf",
58955899
pretty: (): pretty_.Pretty<duration_.Duration> => String,
58965900
arbitrary: (): LazyArbitrary<duration_.Duration> => (fc) =>
@@ -6194,6 +6198,7 @@ export const betweenDuration = <S extends Schema.Any>(
61946198
export class Uint8ArrayFromSelf extends declare(
61956199
Predicate.isUint8Array,
61966200
{
6201+
typeConstructor: { _tag: "Uint8Array" },
61976202
identifier: "Uint8ArrayFromSelf",
61986203
pretty: (): pretty_.Pretty<Uint8Array> => (u8arr) => `new Uint8Array(${JSON.stringify(Array.from(u8arr))})`,
61996204
arbitrary: (): LazyArbitrary<Uint8Array> => (fc) => fc.uint8Array(),
@@ -6781,6 +6786,7 @@ export type DateFromSelfSchemaId = typeof DateFromSelfSchemaId
67816786
export class DateFromSelf extends declare(
67826787
Predicate.isDate,
67836788
{
6789+
typeConstructor: { _tag: "Date" },
67846790
identifier: "DateFromSelf",
67856791
schemaId: DateFromSelfSchemaId,
67866792
[DateFromSelfSchemaId]: { noInvalidDate: false },
@@ -6874,6 +6880,7 @@ export class DateFromNumber extends transform(
68746880
export class DateTimeUtcFromSelf extends declare(
68756881
(u) => dateTime.isDateTime(u) && dateTime.isUtc(u),
68766882
{
6883+
typeConstructor: { _tag: "effect/DateTime.Utc" },
68776884
identifier: "DateTimeUtcFromSelf",
68786885
description: "a DateTime.Utc instance",
68796886
pretty: (): pretty_.Pretty<dateTime.Utc> => (dateTime) => dateTime.toString(),
@@ -6950,6 +6957,7 @@ const timeZoneOffsetArbitrary = (): LazyArbitrary<dateTime.TimeZone.Offset> => (
69506957
export class TimeZoneOffsetFromSelf extends declare(
69516958
dateTime.isTimeZoneOffset,
69526959
{
6960+
typeConstructor: { _tag: "effect/DateTime.TimeZone.Offset" },
69536961
identifier: "TimeZoneOffsetFromSelf",
69546962
description: "a TimeZone.Offset instance",
69556963
pretty: (): pretty_.Pretty<dateTime.TimeZone.Offset> => (zone) => zone.toString(),
@@ -6985,6 +6993,7 @@ const timeZoneNamedArbitrary = (): LazyArbitrary<dateTime.TimeZone.Named> => (fc
69856993
export class TimeZoneNamedFromSelf extends declare(
69866994
dateTime.isTimeZoneNamed,
69876995
{
6996+
typeConstructor: { _tag: "effect/DateTime.TimeZone.Named" },
69886997
identifier: "TimeZoneNamedFromSelf",
69896998
description: "a TimeZone.Named instance",
69906999
pretty: (): pretty_.Pretty<dateTime.TimeZone.Named> => (zone) => zone.toString(),
@@ -7054,6 +7063,7 @@ const timeZoneArbitrary: LazyArbitrary<dateTime.TimeZone> = (fc) =>
70547063
export class DateTimeZonedFromSelf extends declare(
70557064
(u) => dateTime.isDateTime(u) && dateTime.isZoned(u),
70567065
{
7066+
typeConstructor: { _tag: "effect/DateTime.Zoned" },
70577067
identifier: "DateTimeZonedFromSelf",
70587068
description: "a DateTime.Zoned instance",
70597069
pretty: (): pretty_.Pretty<dateTime.Zoned> => (dateTime) => dateTime.toString(),
@@ -7169,6 +7179,7 @@ const OptionFromSelf_ = <Value extends Schema.Any>(value: Value): OptionFromSelf
71697179
encode: (value) => optionParse(ParseResult.encodeUnknown(value))
71707180
},
71717181
{
7182+
typeConstructor: { _tag: "effect/Option" },
71727183
pretty: optionPretty,
71737184
arbitrary: optionArbitrary,
71747185
equivalence: option_.getEquivalence
@@ -7427,6 +7438,7 @@ export const EitherFromSelf = <R extends Schema.All, L extends Schema.All>({ lef
74277438
encode: (right, left) => eitherParse(ParseResult.encodeUnknown(right), ParseResult.encodeUnknown(left))
74287439
},
74297440
{
7441+
typeConstructor: { _tag: "effect/Either" },
74307442
description: `Either<${format(right)}, ${format(left)}>`,
74317443
pretty: eitherPretty,
74327444
arbitrary: eitherArbitrary,
@@ -7615,6 +7627,7 @@ const mapFromSelf_ = <K extends Schema.Any, V extends Schema.Any>(
76157627
encode: (Key, Value) => readonlyMapParse(ParseResult.encodeUnknown(Array$(Tuple(Key, Value))))
76167628
},
76177629
{
7630+
typeConstructor: { _tag: "ReadonlyMap" },
76187631
description,
76197632
pretty: readonlyMapPretty,
76207633
arbitrary: mapArbitrary,
@@ -7797,6 +7810,7 @@ const setFromSelf_ = <Value extends Schema.Any>(value: Value, description: strin
77977810
encode: (item) => readonlySetParse(ParseResult.encodeUnknown(Array$(item)))
77987811
},
77997812
{
7813+
typeConstructor: { _tag: "ReadonlySet" },
78007814
description,
78017815
pretty: readonlySetPretty,
78027816
arbitrary: setArbitrary,
@@ -7898,6 +7912,7 @@ const bigDecimalArbitrary = (): LazyArbitrary<bigDecimal_.BigDecimal> => (fc) =>
78987912
export class BigDecimalFromSelf extends declare(
78997913
bigDecimal_.isBigDecimal,
79007914
{
7915+
typeConstructor: { _tag: "effect/BigDecimal" },
79017916
identifier: "BigDecimalFromSelf",
79027917
pretty: bigDecimalPretty,
79037918
arbitrary: bigDecimalArbitrary,
@@ -8267,6 +8282,7 @@ export const ChunkFromSelf = <Value extends Schema.Any>(value: Value): ChunkFrom
82678282
encode: (item) => chunkParse(ParseResult.encodeUnknown(Array$(item)))
82688283
},
82698284
{
8285+
typeConstructor: { _tag: "effect/Chunk" },
82708286
description: `Chunk<${format(value)}>`,
82718287
pretty: chunkPretty,
82728288
arbitrary: chunkArbitrary,
@@ -8338,6 +8354,7 @@ export const NonEmptyChunkFromSelf = <Value extends Schema.Any>(value: Value): N
83388354
encode: (item) => nonEmptyChunkParse(ParseResult.encodeUnknown(NonEmptyArray(item)))
83398355
},
83408356
{
8357+
typeConstructor: { _tag: "effect/Chunk.NonEmptyChunk" },
83418358
description: `NonEmptyChunk<${format(value)}>`,
83428359
pretty: nonEmptyChunkPretty,
83438360
arbitrary: nonEmptyChunkArbitrary,
@@ -9194,6 +9211,7 @@ const fiberIdPretty: pretty_.Pretty<fiberId_.FiberId> = (fiberId) => {
91949211
export class FiberIdFromSelf extends declare(
91959212
fiberId_.isFiberId,
91969213
{
9214+
typeConstructor: { _tag: "effect/FiberId" },
91979215
identifier: "FiberIdFromSelf",
91989216
pretty: () => fiberIdPretty,
91999217
arbitrary: () => fiberIdArbitrary
@@ -9409,6 +9427,7 @@ export const CauseFromSelf = <E extends Schema.All, D extends Schema.All>({ defe
94099427
encode: (error, defect) => causeParse(ParseResult.encodeUnknown(causeEncoded(error, defect)))
94109428
},
94119429
{
9430+
typeConstructor: { _tag: "effect/Cause" },
94129431
title: `Cause<${error.ast}>`,
94139432
pretty: causePretty,
94149433
arbitrary: causeArbitrary
@@ -9659,6 +9678,7 @@ export const ExitFromSelf = <A extends Schema.All, E extends Schema.All, D exten
96599678
)
96609679
},
96619680
{
9681+
typeConstructor: { _tag: "effect/Exit" },
96629682
title: `Exit<${success.ast}, ${failure.ast}>`,
96639683
pretty: exitPretty,
96649684
arbitrary: exitArbitrary
@@ -9771,6 +9791,7 @@ export const HashSetFromSelf = <Value extends Schema.Any>(
97719791
encode: (item) => hashSetParse(ParseResult.encodeUnknown(Array$(item)))
97729792
},
97739793
{
9794+
typeConstructor: { _tag: "effect/HashSet" },
97749795
description: `HashSet<${format(value)}>`,
97759796
pretty: hashSetPretty,
97769797
arbitrary: hashSetArbitrary,
@@ -9870,6 +9891,7 @@ export const HashMapFromSelf = <K extends Schema.Any, V extends Schema.Any>({ ke
98709891
encode: (key, value) => hashMapParse(ParseResult.encodeUnknown(Array$(Tuple(key, value))))
98719892
},
98729893
{
9894+
typeConstructor: { _tag: "effect/HashMap" },
98739895
description: `HashMap<${format(key)}, ${format(value)}>`,
98749896
pretty: hashMapPretty,
98759897
arbitrary: hashMapArbitrary,
@@ -9956,6 +9978,7 @@ export const ListFromSelf = <Value extends Schema.Any>(
99569978
encode: (item) => listParse(ParseResult.encodeUnknown(Array$(item)))
99579979
},
99589980
{
9981+
typeConstructor: { _tag: "effect/List" },
99599982
description: `List<${format(value)}>`,
99609983
pretty: listPretty,
99619984
arbitrary: listArbitrary,
@@ -10046,6 +10069,7 @@ export const SortedSetFromSelf = <Value extends Schema.Any>(
1004610069
encode: (item) => sortedSetParse(ParseResult.encodeUnknown(Array$(item)), ordI)
1004710070
},
1004810071
{
10072+
typeConstructor: { _tag: "effect/SortedSet" },
1004910073
description: `SortedSet<${format(value)}>`,
1005010074
pretty: sortedSetPretty,
1005110075
arbitrary: (arb, ctx) => sortedSetArbitrary(arb, ordA, ctx),

packages/effect/src/SchemaAST.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ export type AST =
5252
// annotations
5353
// -------------------------------------------------------------------------------------
5454

55+
/**
56+
* @category annotations
57+
* @since 3.19.0
58+
* @experimental
59+
*/
60+
export type TypeConstructorAnnotation = {
61+
readonly _tag: string
62+
[key: PropertyKey]: unknown
63+
}
64+
65+
/**
66+
* @category annotations
67+
* @since 3.19.0
68+
* @experimental
69+
*/
70+
export const TypeConstructorAnnotationId: unique symbol = Symbol.for("effect/annotation/TypeConstructor")
71+
5572
/**
5673
* @category annotations
5774
* @since 3.10.0
@@ -326,6 +343,13 @@ export const getAnnotation: {
326343
Option.none()
327344
)
328345

346+
/**
347+
* @category annotations
348+
* @since 3.19.0
349+
* @experimental
350+
*/
351+
export const getTypeConstructorAnnotation = getAnnotation<TypeConstructorAnnotation>(TypeConstructorAnnotationId)
352+
329353
/**
330354
* @category annotations
331355
* @since 3.10.0

packages/platform/src/Headers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const make = (input: Record.ReadonlyRecord<string, string>): Mutable<Headers> =>
5959
* @category schemas
6060
*/
6161
export const schemaFromSelf: Schema.Schema<Headers> = Schema.declare(isHeaders, {
62+
typeConstructor: { _tag: "effect/platform/Headers" },
6263
identifier: "Headers",
6364
equivalence: () => Record.getEquivalence(String.Equivalence)
6465
})

packages/platform/src/Multipart.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export class MultipartError extends Schema.TaggedError<MultipartError>()("Multip
164164
* @category Schemas
165165
*/
166166
export const FileSchema: Schema.Schema<PersistedFile> = Schema.declare(isPersistedFile, {
167+
typeConstructor: { _tag: "effect/platform/Multipart.PersistedFile" },
167168
identifier: "PersistedFile",
168169
jsonSchema: {
169170
type: "string",

packages/workflow/src/Workflow.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ export class Complete<A, E> extends Data.TaggedClass("Complete")<{
424424
readonly success: Success
425425
readonly error: Error
426426
}): Schema.Schema<Complete<Success["Type"], Error["Type"]>> {
427-
return Schema.declare((u): u is Complete<Success["Type"], Error["Type"]> => isResult(u) && u._tag === "Complete")
427+
return Schema.declare((u): u is Complete<Success["Type"], Error["Type"]> => isResult(u) && u._tag === "Complete", {
428+
typeConstructor: { _tag: "effect/workflow/Workflow.Complete" }
429+
})
428430
}
429431

430432
/**

0 commit comments

Comments
 (0)