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 extends true ? Y : N export type And = If export type Or = If export type Not = If // ------------------------------------------------------------------ // Helpers // ------------------------------------------------------------------ export type Extends = [T] extends [U] ? true : false export type IsAny = 0 extends 1 & T ? true : false export type IsNever = Extends // ------------------------------------------------------------------ // Constraints // ------------------------------------------------------------------ // See https://github.com/microsoft/TypeScript/issues/51011 export type CircularHelper = [T] extends U ? T : Expected // See https://github.com/Microsoft/TypeScript/issues/27024 export type ConstrainEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? T : Expected export type ConstraintMutuallyExtend = CircularHelper // Circular Error on TS 5.4.0 // If U is never, there's nothing we can do // export type ComplexConstraint = If< // // If U is any, we can't use Expect or it would satisfy the constraint // And>, IsAny>, // never, // If< // Or< // // If they are both any we are happy // And, IsAny>, // // If T extends U, but not because it's any, we are happy // And, Not>> // >, // T, // Expected // > // > // ------------------------------------------------------------------ // Expect // ------------------------------------------------------------------ export type ExpectResult = If< IsNever>, { ToStaticNever(): void }, { ToStatic, U>>(): void ToStaticDecode, U>>(): void ToStaticEncode, U>>(): void // ToStatic>(): void // ToStaticDecode>(): void // ToStaticEncode>(): void } > export function Expect(schema: T) { return { ToStatic() {}, ToStaticNever() {}, ToStaticDecode() {}, ToStaticEncode() {}, } as ExpectResult } // ------------------------------------------------------------------ // IsNeverExtends // ------------------------------------------------------------------ /** Special case for left-side `never` as given by `(never extends T ? true : false)` */ export function IsExtendsWhenLeftIsNever(_expect: [TExtendsExpect] extends [true] ? true : false) {} // ------------------------------------------------------------------ // IsExtends // ------------------------------------------------------------------ type TExtendsExpect = Left extends Right ? true : false export function IsExtends(_expect: TExtendsExpect) {} // ------------------------------------------------------------------ // IsExtendsMutual // ------------------------------------------------------------------ type TExtendsMutualExpect = (() => T extends Left ? 1 : 2) extends () => T extends Right ? 1 : 2 ? true : false export function IsExtendsMutual(_expect: TExtendsMutualExpect) {} // ------------------------------------------------------------------ // IsExtendsNever // ------------------------------------------------------------------ type TExtendsNever = [Type] extends [never] ? true : false export function IsExtendsNever(_expect: TExtendsNever) {}