- Rename package from @sinclair/typebox to @alkdev/typebox - Update author, repository, and homepage to alkdev - Remove GitHub workflows, .vscode config, and branding assets - Update all source, test, example, changelog, and task imports - Update tsconfig.json path mappings - Clean up readme header (remove upstream badges/branding)
97 lines
4.4 KiB
TypeScript
97 lines
4.4 KiB
TypeScript
import { Static, StaticDecode, StaticEncode, TSchema } from '@alkdev/typebox'
|
|
|
|
// ------------------------------------------------------------------
|
|
// Symbols
|
|
// ------------------------------------------------------------------
|
|
export declare const Unsatisfiable: unique symbol
|
|
// Warning: `never` and `any` satisfy the constraint `extends Expected<...>`
|
|
export type Expected<_> = { [Unsatisfiable]: never }
|
|
// ------------------------------------------------------------------
|
|
// Gates
|
|
// ------------------------------------------------------------------
|
|
export type If<T, Y, N> = T extends true ? Y : N
|
|
export type And<T, U> = If<T, U, false>
|
|
export type Or<T, U> = If<T, true, U>
|
|
export type Not<T> = If<T, false, true>
|
|
// ------------------------------------------------------------------
|
|
// Helpers
|
|
// ------------------------------------------------------------------
|
|
export type Extends<T, U> = [T] extends [U] ? true : false
|
|
export type IsAny<T> = 0 extends 1 & T ? true : false
|
|
export type IsNever<T> = Extends<T, never>
|
|
// ------------------------------------------------------------------
|
|
// Constraints
|
|
// ------------------------------------------------------------------
|
|
// See https://github.com/microsoft/TypeScript/issues/51011
|
|
export type CircularHelper<T, U> = [T] extends U ? T : Expected<T>
|
|
// See https://github.com/Microsoft/TypeScript/issues/27024
|
|
export type ConstrainEqual<T, U> = (<V>() => V extends T ? 1 : 2) extends <V>() => V extends U ? 1 : 2 ? T : Expected<T>
|
|
export type ConstraintMutuallyExtend<T, U> = CircularHelper<T, [U]>
|
|
|
|
// Circular Error on TS 5.4.0
|
|
// If U is never, there's nothing we can do
|
|
// export type ComplexConstraint<T, U> = If<
|
|
// // If U is any, we can't use Expect<T> or it would satisfy the constraint
|
|
// And<Not<IsAny<T>>, IsAny<U>>,
|
|
// never,
|
|
// If<
|
|
// Or<
|
|
// // If they are both any we are happy
|
|
// And<IsAny<T>, IsAny<U>>,
|
|
// // If T extends U, but not because it's any, we are happy
|
|
// And<Extends<T, U>, Not<IsAny<T>>>
|
|
// >,
|
|
// T,
|
|
// Expected<T>
|
|
// >
|
|
// >
|
|
// ------------------------------------------------------------------
|
|
// Expect
|
|
// ------------------------------------------------------------------
|
|
export type ExpectResult<T extends TSchema> = If<
|
|
IsNever<Static<T>>,
|
|
{ ToStaticNever(): void },
|
|
{
|
|
ToStatic<U extends ConstraintMutuallyExtend<Static<T>, U>>(): void
|
|
ToStaticDecode<U extends ConstraintMutuallyExtend<StaticDecode<T>, U>>(): void
|
|
ToStaticEncode<U extends ConstraintMutuallyExtend<StaticEncode<T>, U>>(): void
|
|
// ToStatic<U extends Static<T>>(): void
|
|
// ToStaticDecode<U extends StaticDecode<T>>(): void
|
|
// ToStaticEncode<U extends StaticEncode<T>>(): void
|
|
}
|
|
>
|
|
export function Expect<T extends TSchema>(schema: T) {
|
|
return {
|
|
ToStatic() {},
|
|
ToStaticNever() {},
|
|
ToStaticDecode() {},
|
|
ToStaticEncode() {},
|
|
} as ExpectResult<T>
|
|
}
|
|
// ------------------------------------------------------------------
|
|
// IsNeverExtends
|
|
// ------------------------------------------------------------------
|
|
/** Special case for left-side `never` as given by `(never extends T ? true : false)` */
|
|
export function IsExtendsWhenLeftIsNever<Left extends unknown, Right extends unknown>(_expect: [TExtendsExpect<Left, Right>] extends [true] ? true : false) {}
|
|
|
|
// ------------------------------------------------------------------
|
|
// IsExtends
|
|
// ------------------------------------------------------------------
|
|
type TExtendsExpect<Left extends unknown, Right extends unknown> = Left extends Right ? true : false
|
|
|
|
export function IsExtends<Left extends unknown, Right extends unknown>(_expect: TExtendsExpect<Left, Right>) {}
|
|
|
|
// ------------------------------------------------------------------
|
|
// IsExtendsMutual
|
|
// ------------------------------------------------------------------
|
|
type TExtendsMutualExpect<Left extends unknown, Right extends unknown> = (<T>() => T extends Left ? 1 : 2) extends <T>() => T extends Right ? 1 : 2 ? true : false
|
|
|
|
export function IsExtendsMutual<Left extends unknown, Right extends unknown>(_expect: TExtendsMutualExpect<Left, Right>) {}
|
|
|
|
// ------------------------------------------------------------------
|
|
// IsExtendsNever
|
|
// ------------------------------------------------------------------
|
|
type TExtendsNever<Type extends unknown> = [Type] extends [never] ? true : false
|
|
|
|
export function IsExtendsNever<Type extends unknown>(_expect: TExtendsNever<Type>) {}
|