UNPKG

@jitl/ts-simple-type

Version:

Static analysis and compiler framework for TypeScript types

1,126 lines 65.5 kB
import * as ts from "typescript"; import * as tsModule from "typescript"; import { Type, TypeChecker, Node, Program, BigIntLiteralType, Declaration, GenericType, LiteralType, ObjectType, Symbol, TupleTypeReference, TypeReference, UniqueESSymbolType } from "typescript"; /** * API to convert SimpleType to strings, and emit those strings in one or more * files. */ import { SourceMapGenerator, SourceNode } from "source-map"; type SimpleTypeKind = // Primitives types "STRING_LITERAL" | "NUMBER_LITERAL" | "BOOLEAN_LITERAL" | "BIG_INT_LITERAL" | "ES_SYMBOL_UNIQUE" | "STRING" | "NUMBER" | "BOOLEAN" | "BIG_INT" | "ES_SYMBOL" | "NULL" | "UNDEFINED" | "VOID" | "NEVER" | "ANY" | "UNKNOWN" | "ENUM" | "ENUM_MEMBER" | "NON_PRIMITIVE" | "UNION" | "INTERSECTION" | "INTERFACE" | "OBJECT" | "CLASS" | "FUNCTION" | "METHOD" | "GENERIC_ARGUMENTS" | "GENERIC_PARAMETER" | "ALIAS" | "TUPLE" | "ARRAY" | "DATE" | "PROMISE"; type SimpleTypeModifierKind = "EXPORT" | "AMBIENT" | "PUBLIC" | "PRIVATE" | "PROTECTED" | "STATIC" | "READONLY" | "ABSTRACT" | "ASYNC" | "DEFAULT"; // ############################## // Base // ############################## interface SimpleTypeAsTypescript { type: ts.Type; checker: ts.TypeChecker; symbol?: ts.Symbol; } interface SimpleTypeBase { readonly kind: SimpleTypeKind; readonly name?: string; readonly error?: string; // Note about methods: it would be great if the converter always added the // methods - then we could make these fields non-optional; but doing so makes // it annoying user code to synthesize SimpleType objects. // So, we'll leave them optional for now. /** * Available if `addMethods` parameter set in `toSimpleType`. */ getTypescript?: () => SimpleTypeAsTypescript; } // ############################## // Primitive Types // ############################## interface SimpleTypeBigIntLiteral extends SimpleTypeBase { readonly kind: "BIG_INT_LITERAL"; readonly value: bigint; } interface SimpleTypeStringLiteral extends SimpleTypeBase { readonly kind: "STRING_LITERAL"; readonly value: string; } interface SimpleTypeNumberLiteral extends SimpleTypeBase { readonly kind: "NUMBER_LITERAL"; readonly value: number; } interface SimpleTypeBooleanLiteral extends SimpleTypeBase { readonly kind: "BOOLEAN_LITERAL"; readonly value: boolean; } interface SimpleTypeString extends SimpleTypeBase { readonly kind: "STRING"; } interface SimpleTypeNumber extends SimpleTypeBase { readonly kind: "NUMBER"; } interface SimpleTypeBoolean extends SimpleTypeBase { readonly kind: "BOOLEAN"; } interface SimpleTypeBigInt extends SimpleTypeBase { readonly kind: "BIG_INT"; } interface SimpleTypeESSymbol extends SimpleTypeBase { readonly kind: "ES_SYMBOL"; } interface SimpleTypeESSymbolUnique extends SimpleTypeBase { readonly kind: "ES_SYMBOL_UNIQUE"; readonly value: string; } // ############################## // TS-specific types // ############################## interface SimpleTypeNull extends SimpleTypeBase { readonly kind: "NULL"; } interface SimpleTypeNever extends SimpleTypeBase { readonly kind: "NEVER"; } interface SimpleTypeUndefined extends SimpleTypeBase { readonly kind: "UNDEFINED"; } interface SimpleTypeAny extends SimpleTypeBase { readonly kind: "ANY"; } interface SimpleTypeUnknown extends SimpleTypeBase { readonly kind: "UNKNOWN"; } interface SimpleTypeVoid extends SimpleTypeBase { readonly kind: "VOID"; } interface SimpleTypeNonPrimitive extends SimpleTypeBase { readonly kind: "NON_PRIMITIVE"; } interface SimpleTypeEnumMember extends SimpleTypeBase { readonly kind: "ENUM_MEMBER"; readonly fullName: string; readonly name: string; readonly type: SimpleTypePrimitive; } interface SimpleTypeEnum extends SimpleTypeBase { readonly name: string; readonly kind: "ENUM"; readonly types: SimpleTypeEnumMember[]; } // ############################## // Structure Types // ############################## interface SimpleTypeUnion extends SimpleTypeBase { readonly kind: "UNION"; readonly types: SimpleType[]; readonly discriminantMembers?: Array<SimpleTypeMemberIndexed | SimpleTypeMemberNamed>; } interface SimpleTypeIntersection extends SimpleTypeBase { readonly kind: "INTERSECTION"; readonly types: SimpleType[]; readonly intersected?: SimpleType; } // ############################## // Object Types // ############################## interface SimpleTypeMemberAsTypescript { memberOfType: ts.Type; symbol: ts.Symbol; checker: ts.TypeChecker; } interface SimpleTypeMember { readonly type: SimpleType; readonly optional?: boolean; readonly modifiers?: SimpleTypeModifierKind[]; getTypescript?: () => SimpleTypeMemberAsTypescript; } interface SimpleTypeMemberNamed extends SimpleTypeMember { readonly name: string; } interface SimpleTypeMemberIndexed extends SimpleTypeMember { readonly index: number; } interface SimpleTypeObjectTypeBase extends SimpleTypeBase { readonly members?: SimpleTypeMemberNamed[]; readonly ctor?: SimpleTypeFunction; readonly call?: SimpleTypeFunction; readonly typeParameters?: SimpleTypeGenericParameter[]; readonly indexType?: { ["STRING"]?: SimpleType; ["NUMBER"]?: SimpleType; }; } interface SimpleTypeInterface extends SimpleTypeObjectTypeBase { readonly kind: "INTERFACE"; } interface SimpleTypeClass extends SimpleTypeObjectTypeBase { readonly kind: "CLASS"; } interface SimpleTypeObject extends SimpleTypeObjectTypeBase { readonly kind: "OBJECT"; } // ############################## // Callable // ############################## interface SimpleTypeFunctionParameter { readonly name: string; readonly type: SimpleType; readonly optional: boolean; readonly rest: boolean; readonly initializer: boolean; } interface SimpleTypeTypePredicate { readonly parameterName: string; readonly parameterIndex: number; readonly type: SimpleType; } interface SimpleTypeFunction extends SimpleTypeBase { readonly kind: "FUNCTION"; readonly parameters?: SimpleTypeFunctionParameter[]; readonly typeParameters?: SimpleTypeGenericParameter[]; readonly returnType?: SimpleType; readonly typePredicate?: SimpleTypeTypePredicate; } interface SimpleTypeMethod extends SimpleTypeBase { readonly kind: "METHOD"; readonly parameters: SimpleTypeFunctionParameter[]; readonly typeParameters?: SimpleTypeGenericParameter[]; readonly returnType: SimpleType; readonly typePredicate?: SimpleTypeTypePredicate; } // ############################## // Generics // ############################## /** * An instantiation of a generic type. * * ``` * type Hello<T> = { hello: T } * type HelloString = Hello<string> * ``` * * Type `HelloString` should be a GENERIC_ARGUMENTS with target of Hello * and a instantiated of `object { hello: string }` */ interface SimpleTypeGenericArguments extends SimpleTypeBase { readonly kind: "GENERIC_ARGUMENTS"; // TODO: rename /** The generic type being instantiated */ readonly target: Extract<SimpleType, { typeParameters?: unknown; }>; /** The arguments passed to the generic */ readonly typeArguments: SimpleType[]; /** The concrete type resulting from applying the type parameters to the generic */ readonly instantiated: SimpleType; // TODO } interface SimpleTypeGenericParameter extends SimpleTypeBase { readonly name: string; readonly kind: "GENERIC_PARAMETER"; readonly default?: SimpleType; readonly constraint?: SimpleType; } interface SimpleTypeAlias extends SimpleTypeBase { readonly kind: "ALIAS"; readonly name: string; readonly target: SimpleType; readonly typeParameters?: SimpleTypeGenericParameter[]; } // ############################## // Lists // ############################## interface SimpleTypeTuple extends SimpleTypeBase { readonly kind: "TUPLE"; readonly members: SimpleTypeMemberIndexed[]; readonly rest?: boolean; } interface SimpleTypeArray extends SimpleTypeBase { readonly kind: "ARRAY"; readonly type: SimpleType; } // ############################## // Special Types // ############################## interface SimpleTypeDate extends SimpleTypeBase { readonly kind: "DATE"; } interface SimpleTypePromise extends SimpleTypeBase { readonly kind: "PROMISE"; readonly type: SimpleType; } type SimpleType = SimpleTypeBigIntLiteral | SimpleTypeEnumMember | SimpleTypeEnum | SimpleTypeClass | SimpleTypeFunction | SimpleTypeObject | SimpleTypeInterface | SimpleTypeTuple | SimpleTypeArray | SimpleTypeUnion | SimpleTypeIntersection | SimpleTypeStringLiteral | SimpleTypeNumberLiteral | SimpleTypeBooleanLiteral | SimpleTypeESSymbolUnique | SimpleTypeString | SimpleTypeNumber | SimpleTypeBoolean | SimpleTypeBigInt | SimpleTypeESSymbol | SimpleTypeNull | SimpleTypeUndefined | SimpleTypeNever | SimpleTypeAny | SimpleTypeMethod | SimpleTypeVoid | SimpleTypeNonPrimitive | SimpleTypePromise | SimpleTypeUnknown | SimpleTypeAlias | SimpleTypeDate | SimpleTypeGenericArguments | SimpleTypeGenericParameter; // Primitive, literal type SimpleTypeLiteral = SimpleTypeBigIntLiteral | SimpleTypeBooleanLiteral | SimpleTypeStringLiteral | SimpleTypeNumberLiteral | SimpleTypeESSymbolUnique; declare const LITERAL_TYPE_KINDS: SimpleTypeKind[]; declare function isSimpleTypeLiteral(type: SimpleType): type is SimpleTypeLiteral; // Primitive type SimpleTypePrimitive = SimpleTypeLiteral | SimpleTypeString | SimpleTypeNumber | SimpleTypeBoolean | SimpleTypeBigInt | SimpleTypeNull | SimpleTypeUndefined | SimpleTypeESSymbol; declare const PRIMITIVE_TYPE_KINDS: SimpleTypeKind[]; declare function isSimpleTypePrimitive(type: SimpleType): type is SimpleTypePrimitive; // All kinds declare const SIMPLE_TYPE_KINDS: SimpleTypeKind[]; declare function isSimpleType(type: unknown): type is SimpleType; type SimpleTypeKindMap = { STRING_LITERAL: SimpleTypeStringLiteral; NUMBER_LITERAL: SimpleTypeNumberLiteral; BOOLEAN_LITERAL: SimpleTypeBooleanLiteral; BIG_INT_LITERAL: SimpleTypeBigIntLiteral; ES_SYMBOL_UNIQUE: SimpleTypeESSymbolUnique; STRING: SimpleTypeString; NUMBER: SimpleTypeNumber; BOOLEAN: SimpleTypeBoolean; BIG_INT: SimpleTypeBigInt; ES_SYMBOL: SimpleTypeESSymbol; NULL: SimpleTypeNull; UNDEFINED: SimpleTypeUndefined; VOID: SimpleTypeVoid; NEVER: SimpleTypeNever; ANY: SimpleTypeAny; UNKNOWN: SimpleTypeUnknown; ENUM: SimpleTypeEnum; ENUM_MEMBER: SimpleTypeEnumMember; NON_PRIMITIVE: SimpleTypeNonPrimitive; UNION: SimpleTypeUnion; INTERSECTION: SimpleTypeIntersection; INTERFACE: SimpleTypeInterface; OBJECT: SimpleTypeObject; CLASS: SimpleTypeClass; FUNCTION: SimpleTypeFunction; METHOD: SimpleTypeMethod; GENERIC_ARGUMENTS: SimpleTypeGenericArguments; GENERIC_PARAMETER: SimpleTypeGenericParameter; ALIAS: SimpleTypeAlias; TUPLE: SimpleTypeTuple; ARRAY: SimpleTypeArray; DATE: SimpleTypeDate; PROMISE: SimpleTypePromise; }; type SimpleTypePathStepKind = "NAMED_MEMBER" | "INDEXED_MEMBER" | "STRING_INDEX" | "NUMBER_INDEX" | "VARIANT" // Union, Intersection, Enum | "AWAITED" | "TYPE_PARAMETER" | "TYPE_PARAMETER_CONSTRAINT" | "TYPE_PARAMETER_DEFAULT" | "PARAMETER" | "RETURN" | "GENERIC_ARGUMENT" | "CALL_SIGNATURE" | "CTOR_SIGNATURE" | "GENERIC_TARGET" | "ALIASED"; interface SimpleTypePathStepBase { step: SimpleTypePathStepKind; from: SimpleType; // TODO: should we really include the "from" type in the path? } interface SimpleTypePathStepNamedMember extends SimpleTypePathStepBase { step: "NAMED_MEMBER"; member: SimpleTypeMemberNamed; // TODO: omit type? index: number; } interface SimpleTypePathStepIndexedMember extends SimpleTypePathStepBase { step: "INDEXED_MEMBER"; member: SimpleTypeMemberIndexed; index: number; } interface SimpleTypePathStepStringIndex extends SimpleTypePathStepBase { step: "STRING_INDEX"; } interface SimpleTypePathStepNumberIndex extends SimpleTypePathStepBase { step: "NUMBER_INDEX"; } /** * Variant in a union, intersection, or enum type. */ interface SimpleTypePathStepVariant extends SimpleTypePathStepBase { step: "VARIANT"; index: number; } interface SimpleTypePathStepAwaited extends SimpleTypePathStepBase { step: "AWAITED"; } interface SimpleTypePathStepTypeParameter extends SimpleTypePathStepBase { step: "TYPE_PARAMETER"; index: number; name: string; } interface SimpleTypePathStepTypeParameterConstraint extends SimpleTypePathStepBase { step: "TYPE_PARAMETER_CONSTRAINT"; } interface SimpleTypePathStepTypeParameterDefault extends SimpleTypePathStepBase { step: "TYPE_PARAMETER_DEFAULT"; } interface SimpleTypePathStepParameter extends SimpleTypePathStepBase { step: "PARAMETER"; index: number; parameter: SimpleTypeFunctionParameter; // TODO: omit type? } interface SimpleTypePathStepReturn extends SimpleTypePathStepBase { step: "RETURN"; } /** Visit a call signature of a interface or class type. Arguably could use "variant", but... */ interface SimpleTypePathStepCallSignature extends SimpleTypePathStepBase { step: "CALL_SIGNATURE"; } /** Visit a call signature of a interface or class type. Arguably could use "variant", but... */ interface SimpleTypePathStepCtorSignature extends SimpleTypePathStepBase { step: "CTOR_SIGNATURE"; } /** * Step from a generic instantiation (GENERIC_ARGUMENTS) to one of the arguments * used for the instantiation. * * ```typescript * interface Foo<T> { * bar: T * } * * // vvvvvv GENERIC_ARGUMENT * type FooInstance = Foo<string> * // ^^^^^^^^^^^ GENERIC_ARGUMENTS * ``` */ interface SimpleTypePathStepGenericArgument extends SimpleTypePathStepBase { step: "GENERIC_ARGUMENT"; index: number; name?: string; } /** * Step from a generic instantiation (GENERIC_ARGUMENTS) to the target of the * instantiation. * * ```typescript * interface Foo<T> { * bar: T * } * * // vvv GENERIC_TARGET * type FooInstance = Foo<string> * // ^^^^^^^^^^^ GENERIC_ARGUMENTS * ``` */ interface SimpleTypePathStepGenericTarget extends SimpleTypePathStepBase { step: "GENERIC_TARGET"; } interface SimpleTypePathStepAliased extends SimpleTypePathStepBase { step: "ALIASED"; } type SimpleTypePathStep = SimpleTypePathStepNamedMember | SimpleTypePathStepIndexedMember | SimpleTypePathStepStringIndex | SimpleTypePathStepNumberIndex | SimpleTypePathStepVariant | SimpleTypePathStepAwaited | SimpleTypePathStepTypeParameter | SimpleTypePathStepTypeParameterConstraint | SimpleTypePathStepTypeParameterDefault | SimpleTypePathStepCallSignature | SimpleTypePathStepCtorSignature | SimpleTypePathStepParameter | SimpleTypePathStepReturn | SimpleTypePathStepGenericArgument | SimpleTypePathStepGenericTarget | SimpleTypePathStepAliased; /** * Describes a traversal path from a starting type to a destination type. * * Given this type: * ```typescript * type Deep = { * foo: { * [key: string]: () => string | number * // ^^^^^^ * } * } * ``` * * A path from `Deep` to the `number` type highlighted would be: * * 1. NAMED_MEMBER (name foo) * 2. STRING_INDEX * 3. RETURN * 4. VARIANT (index 1) */ type SimpleTypePath = SimpleTypePathStep[]; // TODO: consider single linked list to save memory? // TODO: consider single linked list to save memory? declare const SimpleTypePath: { readonly empty: () => SimpleTypePath; readonly includes: (path: SimpleTypePath, type: SimpleType) => boolean; readonly getSubpathFrom: (path: SimpleTypePath, fromType: SimpleType) => SimpleTypePath | undefined; readonly concat: (prefix: SimpleTypePath, suffix: SimpleTypePath | SimpleTypePath[number] | undefined) => SimpleTypePath; readonly last: (path: SimpleTypePath) => SimpleTypePathStep | undefined; readonly lastMustBe: <K extends SimpleTypePathStepKind>(path: SimpleTypePath, ...kind: K[]) => Extract<SimpleTypePathStepNamedMember, { step: K; }> | Extract<SimpleTypePathStepIndexedMember, { step: K; }> | Extract<SimpleTypePathStepStringIndex, { step: K; }> | Extract<SimpleTypePathStepNumberIndex, { step: K; }> | Extract<SimpleTypePathStepVariant, { step: K; }> | Extract<SimpleTypePathStepAwaited, { step: K; }> | Extract<SimpleTypePathStepTypeParameter, { step: K; }> | Extract<SimpleTypePathStepTypeParameterConstraint, { step: K; }> | Extract<SimpleTypePathStepTypeParameterDefault, { step: K; }> | Extract<SimpleTypePathStepCallSignature, { step: K; }> | Extract<SimpleTypePathStepCtorSignature, { step: K; }> | Extract<SimpleTypePathStepParameter, { step: K; }> | Extract<SimpleTypePathStepReturn, { step: K; }> | Extract<SimpleTypePathStepGenericArgument, { step: K; }> | Extract<SimpleTypePathStepGenericTarget, { step: K; }> | Extract<SimpleTypePathStepAliased, { step: K; }>; readonly withoutLast: (path: SimpleTypePath) => SimpleTypePath; readonly toTypeName: (path: SimpleTypePath, target?: SimpleType) => string | undefined; readonly toTypescript: (path: SimpleTypePath) => string; readonly toString: (path: SimpleTypePath, target?: SimpleType) => string; }; declare function unreachable(x: never): never; declare function snakeCaseToCamelCase(snakeCase: string): string; /** Returned by {@link walkRecursive} and similar functions to prevent infinite loops */ declare class Cyclical { readonly cycle: SimpleTypePath; static is(value: unknown): value is Cyclical; static preventCycles<T>(visitor: Visitor<T>): Visitor<T | Cyclical>; constructor(cycle: SimpleTypePath); } interface VisitChild<T, Step extends SimpleTypePath | SimpleTypePath[number] | undefined> { /** Visit the given type with the current visitor */ (step: Step, type: SimpleType): T; /** Visit the given type with a different visitor */ <R>(step: Step, type: SimpleType, fn: Visitor<R>): R; /** * Create a new recursive function with a different visitor. * @warning Currently type inference in GenericVisitor doesn't seem to work for this use-case. */ with<R>(fn: Visitor<R>): VisitChild<R>; } interface VisitorArgs<T, ST extends SimpleType, Step extends SimpleTypePath | SimpleTypePath[number] | undefined> { type: ST; path: SimpleTypePath; visit: VisitChild<T, Step>; } type Visitor<T, ST extends SimpleType> = (args: VisitorArgs<T, ST>) => T; type GenericVisitor<TypeKind extends SimpleType, StepKind extends SimpleTypePathStep> = <T>(args: VisitorArgs<T, TypeKind, StepKind>) => T; type GenericMaybeVisitor<TypeKind extends SimpleType, StepKind extends SimpleTypePathStep> = <T>(args: VisitorArgs<T, TypeKind, StepKind>) => T | undefined; type GenericListVisitor<TypeKind extends SimpleType, StepKind extends SimpleTypePathStep> = <T>(args: VisitorArgs<T, TypeKind, StepKind>) => Array<T>; /** * Perform a custom recursive walk of `type` by calling `fn` it. * `fn` can recurse by calling its `args.visit(path, otherType)`. * @returns result of `fn` */ declare function walkRecursive<T>(path: SimpleTypePath, type: SimpleType, fn: Visitor<T>): T; /** Walk the given SimpleType in depth-first order; does not return a result. */ declare function walkDepthFirst(path: SimpleTypePath, type: SimpleType, visitors: { /** Called before walking the steps inside a type */ before: Visitor<void> | undefined; /** Called after walking the steps inside a type */ after: Visitor<void> | undefined; /** */ traverse?: GenericListVisitor<SimpleType, SimpleTypePathStep>; }): void; // ============================================================================ // Kind-specific visitors. // We should have a visitor in this tree for each edge from a type to another type. // ============================================================================ type SimpleTypePathStepCallable = SimpleTypePathStepTypeParameter[] | SimpleTypePathStepParameter[] | SimpleTypePathStepReturn; type SimpleTypePathStepIndexable = SimpleTypePathStepStringIndex | SimpleTypePathStepNumberIndex; type SimpleTypePathStepObjectLike = SimpleTypePathStepNamedMember[] | SimpleTypePathStepIndexable | SimpleTypePathStepCallSignature | SimpleTypePathStepCtorSignature | SimpleTypePathStepTypeParameter[]; /** * Map from a SimpleTypeKind to the steps you could take from that kind of SimpleType to another SimpleType. * If the kind has multiple edges of that type, they are declared as Step[]. */ interface SimpleTypeToPathStepMap { // STRING_LITERAL: never; // NUMBER_LITERAL: never; // BOOLEAN_LITERAL: never; // BIG_INT_LITERAL: never; // ES_SYMBOL_UNIQUE: never; // STRING: never; // NUMBER: never; // BOOLEAN: never; // BIG_INT: never; // ES_SYMBOL: never; // NULL: never; // UNDEFINED: never; // VOID: never; // NEVER: never; // ANY: never; // UNKNOWN: never; ENUM: SimpleTypePathStepVariant[]; ENUM_MEMBER: SimpleTypePathStepAliased; // NON_PRIMITIVE: never; UNION: SimpleTypePathStepVariant[]; INTERSECTION: SimpleTypePathStepVariant[]; INTERFACE: SimpleTypePathStepObjectLike; OBJECT: SimpleTypePathStepObjectLike; CLASS: SimpleTypePathStepObjectLike; FUNCTION: SimpleTypePathStepCallable; METHOD: SimpleTypePathStepCallable; GENERIC_ARGUMENTS: SimpleTypePathStepGenericArgument[] | SimpleTypePathStepGenericTarget | SimpleTypePathStepAliased; GENERIC_PARAMETER: SimpleTypePathStepTypeParameterConstraint | SimpleTypePathStepTypeParameterDefault; ALIAS: SimpleTypePathStepTypeParameter[] | SimpleTypePathStepAliased; TUPLE: SimpleTypePathStepIndexedMember[]; ARRAY: SimpleTypePathStepNumberIndex; // DATE: never; PROMISE: SimpleTypePathStepAwaited; } type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}` ? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}` : Lowercase<S>; /** The kind-specific visitor API. */ type SimpleTypePathStepVisitors = { [K in keyof SimpleTypeToPathStepMap]: { [SK in Extract<SimpleTypeToPathStepMap[K], SimpleTypePathStepBase> as CamelCase<SK["step"]>]: GenericMaybeVisitor<SimpleTypeKindMap[K], SK>; } & { [SK in Extract<SimpleTypeToPathStepMap[K], Array<any>> as CamelCase<`MAP_${SK[number]["step"]}S`>]: GenericListVisitor<SimpleTypeKindMap[K], SK[number]>; }; }; type FunctionVisitors = SimpleTypePathStepVisitors["FUNCTION"]; type MethodVisitors = SimpleTypePathStepVisitors["METHOD"]; declare class CallableVisitors implements FunctionVisitors, MethodVisitors { static instance: CallableVisitors; mapTypeParameters: GenericListVisitor<SimpleTypeFunction | SimpleTypeMethod, SimpleTypePathStepTypeParameter>; mapParameters: GenericListVisitor<SimpleTypeFunction | SimpleTypeMethod, SimpleTypePathStepParameter>; return: GenericMaybeVisitor<SimpleTypeFunction | SimpleTypeMethod, SimpleTypePathStepReturn>; } type EnumVisitors = SimpleTypePathStepVisitors["ENUM"]; type UnionVisitors = SimpleTypePathStepVisitors["UNION"]; type IntersectionVisitors = SimpleTypePathStepVisitors["INTERSECTION"]; declare class VariantTypesVisitors implements EnumVisitors, UnionVisitors, IntersectionVisitors { static instance: VariantTypesVisitors; mapVariants: GenericListVisitor<SimpleTypeUnion | SimpleTypeEnum | SimpleTypeIntersection, SimpleTypePathStepVariant>; } type InterfaceVisitors = SimpleTypePathStepVisitors["INTERFACE"]; type ObjectVisitors = SimpleTypePathStepVisitors["OBJECT"]; type ClassVisitors = SimpleTypePathStepVisitors["CLASS"]; declare class ObjectLikeVisitors implements InterfaceVisitors, ObjectVisitors, ClassVisitors { static instance: ObjectLikeVisitors; mapTypeParameters: GenericListVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepTypeParameter>; callSignature: GenericMaybeVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepCallSignature>; ctorSignature: GenericMaybeVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepCtorSignature>; mapNamedMembers: GenericListVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepNamedMember>; numberIndex: GenericMaybeVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepNumberIndex>; stringIndex: GenericMaybeVisitor<SimpleTypeInterface | SimpleTypeObject | SimpleTypeClass, SimpleTypePathStepStringIndex>; } type GenericArgumentsVisitorsT = SimpleTypePathStepVisitors["GENERIC_ARGUMENTS"]; declare class GenericArgumentsVisitors implements GenericArgumentsVisitorsT { static instance: GenericArgumentsVisitors; aliased: GenericVisitor<SimpleTypeGenericArguments, SimpleTypePathStepAliased>; genericTarget: GenericVisitor<SimpleTypeGenericArguments, SimpleTypePathStepGenericTarget>; mapGenericArguments: GenericListVisitor<SimpleTypeGenericArguments, SimpleTypePathStepGenericArgument>; } type GenericParameterVisitorsT = SimpleTypePathStepVisitors["GENERIC_PARAMETER"]; declare class GenericParameterVisitors implements GenericParameterVisitorsT { static instance: GenericParameterVisitors; typeParameterConstraint: GenericMaybeVisitor<SimpleTypeGenericParameter, SimpleTypePathStepTypeParameterConstraint>; typeParameterDefault: GenericMaybeVisitor<SimpleTypeGenericParameter, SimpleTypePathStepTypeParameterDefault>; } type TupleVisitorsT = SimpleTypePathStepVisitors["TUPLE"]; declare class TupleVisitors implements TupleVisitorsT { static instance: TupleVisitors; mapIndexedMembers: GenericListVisitor<SimpleTypeTuple, SimpleTypePathStepIndexedMember>; } type AliasVisitors = SimpleTypePathStepVisitors["ALIAS"]; declare class AliasVisitorsImpl implements AliasVisitors { static instance: AliasVisitorsImpl; mapIndexedMembers: GenericListVisitor<SimpleTypeTuple, SimpleTypePathStepIndexedMember>; aliased: GenericVisitor<SimpleTypeAlias, SimpleTypePathStepAliased>; mapTypeParameters: GenericListVisitor<SimpleTypeAlias, SimpleTypePathStepTypeParameter>; } type ArrayVisitorsT = SimpleTypePathStepVisitors["ARRAY"]; declare class ArrayVisitors implements ArrayVisitorsT { static instance: ArrayVisitors; numberIndex: GenericVisitor<SimpleTypeArray, SimpleTypePathStepNumberIndex>; } type PromiseVisitorsT = SimpleTypePathStepVisitors["PROMISE"]; declare class PromiseVisitors implements PromiseVisitorsT { static instance: PromiseVisitors; awaited: GenericVisitor<SimpleTypePromise, SimpleTypePathStepAwaited>; } type EnumMemberVisitorsT = SimpleTypePathStepVisitors["ENUM_MEMBER"]; declare class EnumMemberVisitors implements EnumMemberVisitorsT { static instance: EnumMemberVisitors; aliased: GenericVisitor<SimpleTypeEnumMember, SimpleTypePathStepAliased>; } // ============================================================================ // Higher-level visitors // ============================================================================ declare const mapAnyStep: GenericListVisitor<SimpleType, SimpleTypePathStep>; type SimpleTypeKindVisitors<T> = { [ST in SimpleType as ST["kind"]]: Visitor<T, ST>; }; /** * Visitors for path steps from a SimpleType to other SimpleTypes. * Use these to implement your own type traversals, or inside {@link walkRecursive}. */ declare const Visitor: { mapJsonStep: GenericListVisitor<SimpleType, SimpleTypePathStep>; mapAnyStep: GenericListVisitor<SimpleType, SimpleTypePathStep>; ENUM: VariantTypesVisitors; UNION: VariantTypesVisitors; INTERSECTION: VariantTypesVisitors; INTERFACE: ObjectLikeVisitors; OBJECT: ObjectLikeVisitors; CLASS: ObjectLikeVisitors; FUNCTION: CallableVisitors; METHOD: CallableVisitors; GENERIC_ARGUMENTS: GenericArgumentsVisitors; GENERIC_PARAMETER: GenericParameterVisitors; TUPLE: TupleVisitors; ALIAS: AliasVisitorsImpl; ARRAY: ArrayVisitors; PROMISE: PromiseVisitors; ENUM_MEMBER: EnumMemberVisitors; }; declare function setTypescriptModule(ts: typeof tsModule): void; declare function getTypescriptModule(): typeof tsModule; interface SimpleTypeBaseOptions { } interface SimpleTypeComparisonOptions extends SimpleTypeBaseOptions { strict?: boolean; strictNullChecks?: boolean; strictFunctionTypes?: boolean; noStrictGenericChecks?: boolean; isAssignable?: (typeA: SimpleType, typeB: SimpleType, options: SimpleTypeComparisonOptions) => boolean | undefined | void; debug?: boolean; debugLog?: (text: string) => void; cache?: WeakMap<SimpleType, WeakMap<SimpleType, boolean>>; maxDepth?: number; maxOps?: number; } interface SimpleTypeKindComparisonOptions extends SimpleTypeBaseOptions { matchAny?: boolean; } /** * Tests a type is assignable to a primitive type. * @param type The type to test. * @param options */ declare function isAssignableToPrimitiveType(type: SimpleType): boolean; declare function isAssignableToPrimitiveType(type: Type | SimpleType, checker: TypeChecker): boolean; /** * Tests if "typeA = typeB" in strict mode. * @param typeA - Type A * @param typeB - Type B * @param checkerOrOptions * @param options */ declare function isAssignableToType(typeA: SimpleType, typeB: SimpleType, options?: SimpleTypeComparisonOptions): boolean; declare function isAssignableToType(typeA: SimpleType | Type | Node, typeB: SimpleType | Type | Node, checker: TypeChecker | Program, options?: SimpleTypeComparisonOptions): boolean; declare function isAssignableToType(typeA: Type | Node, typeB: Type | Node, checker: TypeChecker | Program, options?: SimpleTypeComparisonOptions): boolean; declare function isAssignableToType(typeA: Type | Node | SimpleType, typeB: Type | Node | SimpleType, checker: Program | TypeChecker, options?: SimpleTypeComparisonOptions): boolean; /** * Tests if a type is assignable to a value. * Tests "type = value" in strict mode. * @param type The type to test. * @param value The value to test. */ declare function isAssignableToValue(type: SimpleType, value: unknown): boolean; declare function isAssignableToValue(type: SimpleType | Type | Node, value: unknown, checker: TypeChecker | Program): boolean; /** * Checks if a simple type kind is assignable to a type. * @param type The type to check * @param kind The simple type kind to check * @param kind The simple type kind to check * @param checker TypeCHecker if type is a typescript type * @param options Options */ declare function isAssignableToSimpleTypeKind(type: SimpleType, kind: SimpleTypeKind | SimpleTypeKind[], options?: SimpleTypeKindComparisonOptions): boolean; declare function isAssignableToSimpleTypeKind(type: Type | SimpleType, kind: SimpleTypeKind | SimpleTypeKind[], checker: TypeChecker, options?: SimpleTypeKindComparisonOptions): boolean; interface ToSimpleTypeOptions { eager?: boolean; cache?: WeakMap<Type, SimpleType>; /** Add methods like .getType(), .getTypeChecker() to each simple type */ addMethods?: boolean; /** Add { kind: "ALIAS" } wrapper types around simple aliases. Otherwise, remove these wrappers. */ preserveSimpleAliases?: boolean; } /** * Converts a Typescript type to a "SimpleType" * @param type The type to convert. * @param checker * @param options */ declare function toSimpleType(type: SimpleType, checker?: TypeChecker, options?: ToSimpleTypeOptions): SimpleType; declare function toSimpleType(type: Node, checker: TypeChecker, options?: ToSimpleTypeOptions): SimpleType; declare function toSimpleType(type: Type, checker: TypeChecker, options?: ToSimpleTypeOptions): SimpleType; declare function toSimpleType(type: Type | Node | SimpleType, checker: TypeChecker, options?: ToSimpleTypeOptions): SimpleType; declare function debugTypeFlags(type: Type): { typeFlags: Record<string, boolean>; objectFlags: Record<string, boolean>; }; type Writable<T> = { -readonly [K in keyof T]: T[K]; }; /** * Returns a string representation of a given type. * @param simpleType */ declare function typeToString(simpleType: SimpleType): string; declare function typeToString(type: SimpleType | Type, checker: TypeChecker): string; type SerializedSimpleTypeWithRef<ST> = { [key in keyof ST]: ST[key] extends SimpleType ? string : SerializedSimpleTypeWithRef<ST[key]>; }; interface SerializedSimpleType { typeMap: Record<number, SerializedSimpleTypeWithRef>; type: number; } /** * Deserialize a serialized type into a SimpleType * @param serializedSimpleType */ declare function deserializeSimpleType(serializedSimpleType: SerializedSimpleType): SimpleType; /** * Serialize a SimpleType * @param simpleType */ declare function serializeSimpleType(simpleType: SimpleType): SerializedSimpleType; type Chunks = Array<string | SourceNode> | SourceNode | string; /** * SimpleTypeCompiler helps you compile {@link SimpleType}s or TypeScript types * to an arbitrary textual target format. */ declare class SimpleTypeCompiler { readonly checker: ts.TypeChecker; constructor(checker: ts.TypeChecker, getTarget: (compiler: SimpleTypeCompiler) => SimpleTypeCompilerTarget); private target; private current; private toSimpleTypeOptions; /** * Compile a list of entrypoint types. */ compileProgram(entryPoints: Array<{ inputType: SimpleType | ts.Type; outputLocation: SimpleTypeCompilerLocation; }>, outputProgram?: SimpleTypeCompilerProgram): SimpleTypeCompilerOutput; compileType(type: SimpleType | ts.Type, path?: SimpleTypePath, outputLocation?: { fileName: string; namespace?: string[]; }): SimpleTypeCompilerNode; compileReference(referenceArgs: SimpleTypeCompilerReferenceArgs): SimpleTypeCompilerNode; /** * During a call to {@link compileProgram}, this method returns the in-progress program. * You can use it to explicitly add nodes or references to files before they are compiled. */ getCurrentProgram(): SimpleTypeCompilerProgram; /** * During a call to {@link compileProgram} or {@link withLocation}, this method returns the in-progress location. * TODO: make this non-nullable */ getCurrentLocation(): SimpleTypeCompilerLocation | undefined; /** * Perform `fn` with the compiler's location set to `location`. * Use this around the compilation of a declaration that occurs in a different location. */ withLocation<T>(location: SimpleTypeCompilerLocation | undefined, fn: () => T): T; /** * Convert a type to a SimpleType. */ toSimpleType(type: SimpleType | ts.Type): SimpleType; /** * Retrieve typescript information about the given type. * @throws if `type` was converted to SimpleType by a different compiler. */ toTypescript(type: SimpleType): SimpleTypeAsTypescript; /** * Retrieve typescript information about the given member. * @throws if `type` was compiled by a different compiler. */ toTypescript(type: SimpleTypeMember): SimpleTypeMemberAsTypescript; /** * Return the type's name, or try to infer one if it is anonymous. */ inferTypeName(type: SimpleType, path: SimpleTypePath): string; /** * Find the type's source location. Returns the relevant Typescript source location objects, * as well as an object formatted for source mapping. */ getSourceLocation: typeof getSourceLocationOfSimpleType; getDocumentationComment(typeOrMember: SimpleType | SimpleTypeMember): { docComment?: string; jsDocTags?: Map<string, string | undefined>; } | undefined; /** * @returns true if `type` is exported from its source declaration file. */ isExportedFromSourceLocation(type: SimpleType): boolean; createUniqueLocation(type: SimpleType, path: SimpleTypePath, suggestedLocation: SimpleTypeCompilerLocation): SimpleTypeCompilerDeclarationLocation; /** * Assign a declaration location in the output program to the given `type`. * If the type already has an assigned declaration location, it's returned instead. * By default, the location will be a unique name inside the current file and namespace of the compiler. * * Once a location is assigned to a type, the compiler can use references to that location instead * of repeatedly compiling the same type. This is critical for recursive type definitions. * * It is the caller's responsibility to ensure a {@link SimpleTypeCompilerDeclarationNode} * exists at that location in the compiler's output. * * @param location Assign the type to this location. * @returns The assigned location, suitable for use */ assignDeclarationLocation(type: SimpleType, path: SimpleTypePath, location?: SimpleTypeCompilerLocation): SimpleTypeCompilerDeclarationLocation; /** * Create an AST node builder. * @param type AST nodes will be source-mapped to the input declaration location of this type. * @param path AST nodes will reference this path. Useful for debugging. * @param location An alternate output location, used when building references to locations or declarations. See {@link SimpleTypeCompilerNodeBuilder#reference}. */ nodeBuilder(type: SimpleType, path: SimpleTypePath, location?: SimpleTypeCompilerLocation): SimpleTypeCompilerNodeBuilder; /** * Create an AST node builder without an associated type. * Prefer to use {@link nodeBuilder} when compiling types. * @param location An alternate output location, used when building references to locations or declarations. See {@link SimpleTypeCompilerNodeBuilder#reference}. */ anonymousNodeBuilder(location?: SimpleTypeCompilerLocation): SimpleTypeCompilerNodeBuilder; private withState; } declare function getSourceLocationOfSimpleType(type: SimpleType): { typescript: undefined; sourceMap: { source: null; sourceContent: null; line: null; column: null; }; } | { typescript: { symbol: ts.Symbol; declaration: ts.Declaration; sourceFile: ts.SourceFile; type: ts.Type; checker: ts.TypeChecker; }; sourceMap: { column: number; line: number; source: string; sourceContent: string; }; }; declare class SimpleTypeCompilerNodeBuilder { private type; private path; private fromLocation; private compiler; constructor(type: SimpleType | undefined, path: SimpleTypePath | undefined, fromLocation: SimpleTypeCompilerLocation | undefined, compiler: SimpleTypeCompiler); private nodeOfType; isNode(node: object): node is SimpleTypeCompilerNode; /** Create an output AST node */ node(template: TemplateStringsArray, ...chunks: Chunks[]): SimpleTypeCompilerNode; /** Create an output AST node */ node(chunks: Chunks): SimpleTypeCompilerNode; /** * Map over the given nodes, returning a {@link SimpleTypeCompilerReferenceNode} for any declaration nodes. */ references(nodes: SimpleTypeCompilerNode[]): SimpleTypeCompilerNode; /** Create a new reference node. */ reference(toLocation: { location: SimpleTypeCompilerDeclarationLocation; }, chunks: Chunks): SimpleTypeCompilerReferenceNode; /** Compile a reference to the given declaration. */ reference(toLocation: { location: SimpleTypeCompilerDeclarationLocation; }): SimpleTypeCompilerReferenceNode; /** Create a new reference node. */ reference(toDeclaration: SimpleTypeCompilerDeclarationNode, chunks: Chunks): SimpleTypeCompilerDeclarationReferenceNode; /** Compile a reference to the given declaration. */ reference(toDeclaration: SimpleTypeCompilerDeclarationNode): SimpleTypeCompilerDeclarationReferenceNode; /** Compile a reference to the given node if it's a declaration. Otherwise, return the node. */ reference(toNode: SimpleTypeCompilerNode): SimpleTypeCompilerNode; reference(toNode: SimpleTypeCompilerNode | undefined): SimpleTypeCompilerNode | undefined; isDeclaration(node: object): node is SimpleTypeCompilerDeclarationNode; assertDeclaration(node: SimpleTypeCompilerNode): asserts node is SimpleTypeCompilerDeclarationNode; /** * Create a declaration node at the given location. * @param location The declaration will be rendered in this file by the compilation. */ declaration(location: SimpleTypeCompilerDeclarationLocation, chunks: Chunks): SimpleTypeCompilerDeclarationNode; } interface SourceNodeConstructor<T> { new (line: number | null, column: number | null, source: string | null, chunks?: Chunks, name?: string): T; } declare class SimpleTypeCompilerNode extends SourceNode { static forType<T extends SimpleTypeCompilerNode>(this: SourceNodeConstructor<T>, type: SimpleType, path: SimpleTypePath, chunks: Chunks): T; static fromScratch<T extends SimpleTypeCompilerNode>(this: SourceNodeConstructor<T>, chunks: Chunks): T; type?: SimpleType; path?: SimpleTypePath; step?: SimpleTypePathStep; shouldCache: boolean; /** * Mark this node as non-cacheable for a type. * Use this method when you may compile a type two different ways depending on * how it's referenced. Eg, for an enum member should be compiled one way * inside its containing enum declaration, and another way when referenced by a * member in another type. */ doNotCache(): this; // Improve typing to `this` : https://github.com/mozilla/source-map/blob/58819f09018d56ef84dc41ba9c93f554e0645169/lib/source-node.js#L271 /** * Mutate this node by inserting `sep` between every child. */ joinNodes(sep: string): this; } declare class SimpleTypeCompilerDeclarationNode extends SimpleTypeCompilerNode { location: SimpleTypeCompilerDeclarationLocation; } declare class SimpleTypeCompilerReferenceNode extends SimpleTypeCompilerNode { refersTo: SimpleTypeCompilerDeclarationLocation; shouldCache: boolean; } declare class SimpleTypeCompilerDeclarationReferenceNode extends SimpleTypeCompilerReferenceNode { refersToDeclaration: SimpleTypeCompilerDeclarationNode; } interface SimpleTypeCompilerLocation { fileName: string; namespace?: string[]; name?: string; } interface SimpleTypeCompilerDeclarationLocation extends SimpleTypeCompilerLocation { name: string; toString?: () => string; } declare const SimpleTypeCompilerLocation: { fileNameEqual(a: SimpleTypeCompilerLocation, b: SimpleTypeCompilerLocation): boolean; namespaceEqual(a: SimpleTypeCompilerLocation, b: SimpleTypeCompilerLocation): boolean; fileAndNamespaceEqual(a: SimpleTypeCompilerLocation, b: SimpleTypeCompilerLocation): boolean; nestInside(parentLocation: SimpleTypeCompilerDeclarationLocation): SimpleTypeCompilerLocation; }; declare class SimpleTypeCompilerProgram { entryPoints: Map<SimpleType, SimpleTypeCompilerDeclarationLocation>; files: Map<string, SimpleTypeCompilerTargetFile>; private declarationLocationNameCount; private typeToDeclarationLocationCache; private typeToAstNodeCache; getOrCreateFile(fileName: string): SimpleTypeCompilerTargetFile; getDeclarationLocation(type: SimpleType): SimpleTypeCompilerDeclarationLocation | undefined; setDeclarationLocation(type: SimpleType, location: SimpleTypeCompilerDeclarationLocation): void; getDeclarationLocationCount(location: SimpleTypeCompilerDeclarationLocation): number; setDeclarationLocationCount(location: SimpleTypeCompilerDeclarationLocation, count: number): void; getAstNode(type: SimpleType): SimpleTypeCompilerNode | undefined; setAstNode(type: SimpleType, node: SimpleTypeCompilerNode): void; } declare class SimpleTypeCompilerTargetFile { fileName: string; constructor(fileName: string); private _references; private _nodes; get references(): readonly SimpleTypeCompilerDeclarationLocation[]; addReference(location: SimpleTypeCompilerDeclarationLocation): void; get nodes(): readonly SimpleTypeCompilerNode[]; addNode(node: SimpleTypeCompilerNode): void; get isEmpty(): boolean; } interface SimpleTypeCompilerOutputFile { fileName: string; compiledFrom: SimpleTypeCompilerTargetFile; ast: SimpleTypeCompilerNode; text: string; sourceMap: SourceMapGenerator; } interface SimpleTypeCompilerOutput { files: Map<string, SimpleTypeCompilerOutputFile>; program: SimpleTypeCompilerProgram; } interface SimpleTypeCompilerReferenceArgs { from: SimpleTypeCompilerLocation; to: { location: SimpleTypeCompilerDeclarationLocation; } | SimpleTypeCompilerDeclarationNode; } interface SimpleTypeCompilerTarget { /** * Called by the type compiler to compile a type. * Most of a compiler target's logic lives in this function. * * Use {@link SimpleTypeCompiler#nodeBuilder} to create nodes during the compilation. */ compileType: Visitor<SimpleTypeCompilerNode>; /** * Called by the type compiler if you build a reference node using a location. * * @see {@link SimpleTypeCompilerNodeBuilder#reference} */ compileReference(args: SimpleTypeCompilerReferenceArgs): SimpleTypeCompilerNode; /** * Compile a file that contains one or more declarations. */ compileFile(file: SimpleTypeCompilerTargetFile): SimpleTypeCompilerNode; /** * Called by the type compiler in {@link SimpleTypeCompiler#assignDeclarationLocation}. * * Assign a destination file and namespace to a type when it's compiled to declaration node. * If you have no opinion about the placement of this type, you can return `from` - which will place it in the current file and namespace. * * @param type The type to assign a destination declaration location to. * @param from The current file and namespace we are compiling from. */ suggestDeclarationLocation?: (type: SimpleType, from: SimpleTypeCompilerLocation) => SimpleTypeCompilerLocation | SimpleTypeCompilerDeclarationLocation; } declare function validateType(type: SimpleType, callback: (simpleType: SimpleType) => boolean | undefined | void): boolean; declare namespace unstableTsUtils { type SimpleTypeKind = // Primitives types "STRING_LITERAL" | "NUMBER_LITERAL" | "BOOLEAN_LITERAL" | "BIG_INT_LITERAL" | "ES_SYMBOL_UNIQUE" | "STRING" | "NUMBER" | "BOOLEAN" | "BIG_INT" | "ES_SYMBOL" | "NULL" | "UNDEFINED" | "VOID" | "NEVER" | "ANY" | "UNKNOWN" | "ENUM" | "ENUM_MEMBER" | "NON_PRIMITIVE" | "UNION" | "INTERSECTION" | "INTERFACE" | "OBJECT" | "CLASS" | "FUNCTION" | "METHOD" | "GENERIC_ARGUMENTS" | "GENERIC_PARAMETER" | "ALIAS" | "TUPLE" | "ARRAY" | "DATE" | "PROMISE"; type SimpleTypeModifierKind = "EXPORT" | "AMBIENT" | "PUBLIC" | "PRIVATE" | "PROTECTED" | "STATIC" | "READONLY" | "ABSTRACT" | "ASYNC" | "DEFAULT"; // ############################## // Base // ############################## interface SimpleTypeAsTypescript { type: ts.Type; checker: ts.TypeChecker; symbol?: ts.Symbol; } interface SimpleTypeBase { readonly kind: SimpleTypeKind; readonly name?: string; readonly error?: string; // Note about methods: it would be great if the converter always added the // methods - then we could make these fields non-optional; but doing so makes // it annoying user code to synthesize SimpleType objects. // So, we'll leave them optional for now. /** * Available if `addMethods` parameter set in `toSimpleType`. */ getTypescript?: () => SimpleTypeAsTypescript; } // ############################## // Primitive Types // ############################## interface SimpleTypeBigIntLiteral extends SimpleTypeBase { readonly kind: "BIG_INT_LITERAL"; readonly value: bigint; } interface SimpleTypeStringLiteral extends SimpleTypeBase { readonly kind: "STRING_LITERAL"; readonly value: string; } interface SimpleTypeNumberLiteral extends SimpleTypeBase { readonly kind: "NUMBER_LITERAL"; readonly value: number; } interface SimpleTypeBooleanLiteral extends SimpleTypeBase { readonly kind: "BOOLEAN_LITERAL"; readonly value: boolean; } interface SimpleTypeString extends SimpleTypeBase { readonly kind: "STRING"; } interface SimpleTypeNumber extends SimpleTypeBase { readonly kind: "NUMBER"; } interface SimpleTypeBoolean extends SimpleTypeBase { readonly kind: "BOOLEAN"; } interface SimpleTypeBigInt extends SimpleTypeBase { readonly kind: "BIG_INT"; } interface SimpleTypeESSymbol extends SimpleTypeBase { readonly kind: "ES_SYMBOL"; } interface SimpleTypeESSymbolUnique extends SimpleTypeBase { readonly kind: "ES_SYMBOL_UNIQUE"; readonly value: string; } // ############################## // TS-specific types // ############################## interface SimpleTypeNull extends SimpleTypeBase { readonly kind: "NULL"; } interface SimpleTypeNever extends SimpleTypeBase { readonly kind: "NEVER"; } interface SimpleTypeUndefined extends SimpleTypeBase { readonly kind: "UNDEFINED"; } interface SimpleTypeAny extends SimpleTypeBase { readonly kind: "ANY"; } interface SimpleTypeUnknown extends SimpleTypeBase { readonly kind: "UNKNOWN"; } interface SimpleTypeVoid extends SimpleTypeBase { readonly kind: "VOID"; } interface SimpleTypeNonPrimitive exte