import { DeepBrandOptions, DeepBrandOptionsDefaults, StrictEqualUsingBranding } from './branding'; import type { And, Extends, ExtendsExcludingAnyOrNever, IsAny, IsNever, IsUnknown, Not, OptionalKeys, StrictEqualUsingTSInternalIdenticalToOperator, UsefulKeys } from './utils'; /** * Determines the printable type representation for a given type. */ export type PrintType = IsUnknown extends true ? 'unknown' : IsNever extends true ? 'never' : IsAny extends true ? never : boolean extends T ? 'boolean' : T extends boolean ? `literal boolean: ${T}` : string extends T ? 'string' : T extends string ? `literal string: ${T}` : number extends T ? 'number' : T extends number ? `literal number: ${T}` : bigint extends T ? 'bigint' : T extends bigint ? `literal bigint: ${T}` : T extends null ? 'null' : T extends undefined ? 'undefined' : T extends (...args: any[]) => any ? 'function' : '...'; /** * Helper for showing end-user a hint why their type assertion is failing. * This swaps "leaf" types with a literal message about what the actual and * expected types are. Needs to check for `Not>` because * otherwise `LeafTypeOf` returns `never`, which extends everything 🤔 */ export type MismatchInfo = And<[Extends, '...'>, Not>]> extends true ? And<[Extends, Extends]> extends true ? Array[number], Extract[number], Options>> : Optionalify<{ [K in UsefulKeys | UsefulKeys]: MismatchInfo; }, OptionalKeys> : StrictEqualUsingBranding extends true ? Actual : `Expected: ${PrintType}, Actual: ${PrintType>}`; /** * Helper for making some keys of a type optional. Only useful so far for `MismatchInfo` - it makes sure we * don't get bogus errors about optional properties mismatching, when actually it's something else that's wrong. * * - Note: this helper is a no-op if there are no optional keys in the type. */ export type Optionalify = [TOptionalKeys] extends [never] ? T : ({ [K in Exclude]: T[K]; } & { [K in Extract]?: T[K]; }) extends infer X ? { [K in keyof X]: X[K]; } : never; /** * @internal */ declare const inverted: unique symbol; /** * @internal */ type Inverted = { [inverted]: T; }; /** * @internal */ declare const expectNull: unique symbol; export type ExpectNull = { [expectNull]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectUndefined: unique symbol; export type ExpectUndefined = { [expectUndefined]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectNumber: unique symbol; export type ExpectNumber = { [expectNumber]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectString: unique symbol; export type ExpectString = { [expectString]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectBoolean: unique symbol; export type ExpectBoolean = { [expectBoolean]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectVoid: unique symbol; export type ExpectVoid = { [expectVoid]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectFunction: unique symbol; export type ExpectFunction = { [expectFunction]: T; result: ExtendsExcludingAnyOrNever any>; }; /** * @internal */ declare const expectObject: unique symbol; export type ExpectObject = { [expectObject]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectArray: unique symbol; export type ExpectArray = { [expectArray]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectSymbol: unique symbol; export type ExpectSymbol = { [expectSymbol]: T; result: ExtendsExcludingAnyOrNever; }; /** * @internal */ declare const expectAny: unique symbol; export type ExpectAny = { [expectAny]: T; result: IsAny; }; /** * @internal */ declare const expectUnknown: unique symbol; export type ExpectUnknown = { [expectUnknown]: T; result: IsUnknown; }; /** * @internal */ declare const expectNever: unique symbol; export type ExpectNever = { [expectNever]: T; result: IsNever; }; /** * @internal */ declare const expectNullable: unique symbol; export type ExpectNullable = { [expectNullable]: T; result: Not>>; }; /** * @internal */ declare const expectBigInt: unique symbol; export type ExpectBigInt = { [expectBigInt]: T; result: ExtendsExcludingAnyOrNever; }; /** * Checks if the result of an expecter matches the specified options, and * resolves to a fairly readable error message if not. */ export type Scolder = Expecter['result'] extends Options['positive'] ? () => true : Options['positive'] extends true ? Expecter : Inverted; export {};