import { DiffUnions, ElementOf, Evaluate, IsAny, KeyValuate, MergeAll, StringifyPossibleTypes, StringReplace, UnionDiffResult } from "@re-do/utils" import { ParsedType } from "../../parse.js" import { ParseConfig } from "./internal.js" import { TypeSetMember } from "./member.js" import { Root } from "../root.js" import { Obj } from "../recursible" export namespace TypeSet { export type Definition = Obj.Definition export type TypeNameFromList = keyof MergeAll & string export type ValidateMemberList< Definitions, DeclaredTypeNames extends string[] = [], Merged = TypeSet.Validate>, DefinedTypeName extends string = keyof Merged & string, DeclaredTypeName extends string = DeclaredTypeNames extends never[] ? DefinedTypeName : ElementOf, ErrorMessage extends string = MissingTypesError< DeclaredTypeName, DefinedTypeName > > = { [I in keyof Definitions]: ErrorMessage & { [TypeName in keyof Definitions[I]]: TypeName extends DeclaredTypeName ? KeyValuate : `${TypeName & string} was never declared.` } } export type MergeMemberList = MergeAll // Just use unknown for now since we don't have all the definitions yet // but we still want to allow references to other declared types export type ValidateReferences< Def, DeclaredTypeName extends string > = Root.Validate< Def, { [TypeName in DeclaredTypeName]: "unknown" } > export type Validate = IsAny extends true ? any : Evaluate<{ [TypeName in keyof TypeSet]: TypeSetMember.Validate< TypeSet[TypeName], TypeSet > }> export type Parse = { [TypeName in keyof TypeSet]: ParsedType< TypeSet[TypeName], Validate, Options > } } export const extraneousTypesErrorMessage = `Defined types @types were never declared.` export const missingTypesErrorMessage = `Declared types @types were never defined.` export type MissingTypesError = DiffUnions< DeclaredTypeName, DefinedTypeName // Extraneous definition errors are handled by ValidateMemberList > extends UnionDiffResult ? Missing extends [] ? {} : StringReplace< typeof missingTypesErrorMessage, "@types", StringifyPossibleTypes<`'${ElementOf}'`> > : never