import type { ClassTuple } from ".//Util/class.ts"; import * as S from "./Schema.ts"; export declare function defineTrait( tag: NoInfer["tag"]>, fn: F, ): TraitDef; export declare function defineTrait( tag: T["tag"], props: { [k in keyof TraitProps]: TraitProps[k]; }, ): TraitDef<(target: Target) => ApplyTrait>; export const applyTrait = >( tag: T["tag"], props: { [k in keyof TraitProps]: TraitProps[k]; }, ): T => undefined!; export type AnyTrait = Trait; export type TraitFn< T extends AnyTrait = AnyTrait, Args extends any[] = any[], > = (...args: Args) => T; export type TraitDef = Fn & { /** @internal phantom */ trait: ReturnType; }; export interface Trait< Tag extends string = string, Errors extends any[] = never, Provides extends any[] = never, > { type?: "trait"; tag: Tag; errors?: ClassTuple; provides?: ClassTuple; } export type TraitError> = InstanceType< Exclude[number] >; export type TraitProps> = { [k in keyof _TraitProps]: _TraitProps[k]; }; type _TraitProps> = Omit< A, "type" | "tag" | "provides" | "errors" > & (A["errors"] extends never | undefined ? {} : { errors: Exclude; }) & (A["provides"] extends never | undefined ? {} : { provides: Exclude; }); export type ApplyTrait> = ([ Target, ] extends [Annotated] ? Annotated : [Target] extends [S.Top] ? Annotated : [Target] extends [S.AnyClassSchema] ? Annotated> : Target) & {}; export type Annotated> = S & { /** @internal phantom type */ S: S; type: "annotated"; /** @internal phatom */ traits: T; }; export declare namespace Annotated { export type Unwrap = T extends Annotated ? t : never; } // export declare namespace Traits { // export type Of = C extends Seen // ? never // : C extends Annotated // ? T | Of // : C extends AnyClassSchema // ? OfFields // : C extends S.Struct // ? OfFields // : never; // type OfFields = { // [prop in keyof F]: Of; // }[keyof F]; // }