mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 01:31:22 +03:00
refactor(core): delete unused Newtype helper (#52647)
This commit is contained in:
committed by
GitHub
Unverified
parent
317dfbc6b3
commit
e366ab40c4
@@ -1,4 +1,3 @@
|
||||
import { Schema } from "effect"
|
||||
import {
|
||||
AbsolutePath,
|
||||
DateTimeUtcFromMillis,
|
||||
@@ -38,52 +37,3 @@ export type DeepMutable<T> = T extends string | number | boolean | bigint | symb
|
||||
: T extends object
|
||||
? { -readonly [K in keyof T]: DeepMutable<T[K]> }
|
||||
: T
|
||||
|
||||
/**
|
||||
* Nominal wrapper for scalar types. The class itself is a valid schema —
|
||||
* pass it directly to `Schema.decodeUnknownSync`, `Schema.decodeEffect`, etc.
|
||||
*
|
||||
* The runtime value remains an unwrapped primitive. `Schema.brand` supplies
|
||||
* the primitive schema behavior and constructor validation, while the class
|
||||
* supplies the nominal TypeScript identity.
|
||||
* Apply checks and annotations to the underlying schema before wrapping it;
|
||||
* schema rebuild operations intentionally return the underlying schema shape.
|
||||
*
|
||||
* @example
|
||||
* class QuestionID extends Newtype<QuestionID>()("QuestionID", Schema.String) {}
|
||||
*
|
||||
* const id = QuestionID.make("question-1")
|
||||
* Schema.decodeUnknownEffect(QuestionID)(input)
|
||||
*/
|
||||
type NewtypeSchema<Self, Tag extends string, S extends Schema.Top> = (abstract new (_: never) => {
|
||||
readonly _newtype: Tag
|
||||
}) &
|
||||
Schema.BottomWithoutNew<
|
||||
Self,
|
||||
S["Encoded"],
|
||||
S["DecodingServices"],
|
||||
S["EncodingServices"],
|
||||
S["ast"],
|
||||
S["Rebuild"],
|
||||
S["~type.make.in"],
|
||||
Self,
|
||||
S["~type.parameters"],
|
||||
Self,
|
||||
S["~type.mutability"],
|
||||
S["~type.optionality"],
|
||||
S["~type.constructor.default"],
|
||||
S["~encoded.mutability"],
|
||||
S["~encoded.optionality"]
|
||||
> &
|
||||
Omit<S, keyof Schema.Top>
|
||||
|
||||
export function Newtype<Self>() {
|
||||
return <const Tag extends string, S extends Schema.Top>(tag: Tag, schema: S): NewtypeSchema<Self, Tag, S> => {
|
||||
abstract class Base {
|
||||
declare readonly _newtype: Tag
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(Base, schema.pipe(Schema.brand(tag)))
|
||||
return Base as unknown as NewtypeSchema<Self, Tag, S>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
import { expect, test } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { Newtype } from "../src/schema"
|
||||
|
||||
class UserID extends Newtype<UserID>()("Test.UserID", Schema.NonEmptyString) {}
|
||||
class ProjectID extends Newtype<ProjectID>()("Test.ProjectID", Schema.NonEmptyString) {}
|
||||
class Port extends Newtype<Port>()("Test.Port", Schema.FiniteFromString) {}
|
||||
|
||||
const User = Schema.Struct({ id: UserID })
|
||||
|
||||
test("constructs nominal values from the underlying type", () => {
|
||||
const id = UserID.make("user-1")
|
||||
const acceptUserID = (_id: UserID) => undefined
|
||||
|
||||
expect(String(id)).toBe("user-1")
|
||||
acceptUserID(id)
|
||||
|
||||
if (false) {
|
||||
// @ts-expect-error distinct newtypes are not interchangeable
|
||||
acceptUserID(ProjectID.make("project-1"))
|
||||
}
|
||||
})
|
||||
|
||||
test("preserves constructor validation", () => {
|
||||
expect(() => UserID.make("")).toThrow()
|
||||
})
|
||||
|
||||
test("decodes and encodes as a schema", async () => {
|
||||
const decoded = await Effect.runPromise(Schema.decodeUnknownEffect(User)({ id: "user-1" }))
|
||||
const encoded = await Effect.runPromise(Schema.encodeEffect(User)(decoded))
|
||||
|
||||
expect(String(decoded.id)).toBe("user-1")
|
||||
expect(encoded).toEqual({ id: "user-1" })
|
||||
})
|
||||
|
||||
test("preserves the underlying schema validation", async () => {
|
||||
const result = await Effect.runPromise(Schema.decodeUnknownEffect(UserID)("").pipe(Effect.result))
|
||||
expect(result._tag).toBe("Failure")
|
||||
})
|
||||
|
||||
test("preserves transformed encoded and decoded representations", async () => {
|
||||
const decoded = await Effect.runPromise(Schema.decodeUnknownEffect(Port)("8080"))
|
||||
const encoded = await Effect.runPromise(Schema.encodeEffect(Port)(decoded))
|
||||
|
||||
expect(Number(decoded)).toBe(8080)
|
||||
expect(encoded).toBe("8080")
|
||||
})
|
||||
Reference in New Issue
Block a user