UNPKG

generic-type-guard

Version:
543 lines (486 loc) 16.9 kB
/** * Asserts that a guard is successful. * * This may not work properly in ECMAScript environments that don't fully support ES6. If this is your environment then * you should do this check manually and throw your own error. * * @throws AssertionError if the guard returns false. * @public */ export declare const assert: <T, Guard extends PartialTypeGuard<T, T>>(value: T, guard: Guard, message?: string) => asserts value is GuardedType<Guard>; /** * Indicates there was an error validating a typeguard. * * @public */ export declare class AssertionError extends RangeError { value: unknown; constructor(value: unknown, message?: string); } /** * Helper to string many different typeguards together into something larger. * * @param guards - A list of partial typeguards to string together. * * @public */ export declare const combine: { <A, B extends A, C extends B>(g1: PartialTypeGuard<A, B>, g2: PartialTypeGuard<B, C>): PartialTypeGuard<A, C>; <A, B extends A, C extends B, D extends C>(g1: PartialTypeGuard<A, B>, g2: PartialTypeGuard<B, C>, g3: PartialTypeGuard<C, D>): PartialTypeGuard<A, D>; <A, B extends A, C extends B, D extends C, E extends D>(g1: PartialTypeGuard<A, B>, g2: PartialTypeGuard<B, C>, g3: PartialTypeGuard<C, D>, g4: PartialTypeGuard<D, E>): PartialTypeGuard<A, E>; <A, B extends A, C extends B, D extends C, E extends D, F extends E>(g1: PartialTypeGuard<A, B>, g2: PartialTypeGuard<B, C>, g3: PartialTypeGuard<C, D>, g4: PartialTypeGuard<D, E>, g5: PartialTypeGuard<D, E>): PartialTypeGuard<A, F>; }; /** * Helper to diff types. * @public */ export declare type Diff<T, U> = T extends U ? never : T; /** * Extracts the type that is being guarded for from a type guard. * * @public */ export declare type GuardedType<T extends PartialTypeGuard<any, unknown>> = T extends PartialTypeGuard<any, infer U> ? U : never; /** * Validates that a given object has a numeric index signature. * * @param enforce - Whether to enforce that there is at least one property already set. Be careful setting this to * false, you will get some unexpected outputs, for instance objects will have a numeric index signature. * * @public */ export declare const hasNumericIndexSignature: <V>(value: TypeGuard<V>, enforce?: boolean) => PartialTypeGuard<object, Record<number, V>>; /** * Validate that a given object only has the given properties * * @param props - A MappedTypeGuard of the object to be validated. * * @public */ export declare const hasOnlyProperties: <V extends object>(props: MappedTypeGuard<V>) => PartialTypeGuard<object, V>; /** * Validate that a given object has all the given optional properties * * @param props - a MappedGuard of the object to be validated, i.e. an object that has the same properties as the * object being validated whose types are TypeGuards for the matching type on the original property. * * @public */ export declare const hasOptionalProperties: <V extends object>(props: MappedTypeGuard<V>) => PartialTypeGuard<object, Partial<V>>; /** * Validates that a given object has an optional property of a given type. * * @public */ export declare const hasOptionalProperty: <K extends string, V>(property: K, value: TypeGuard<V>) => PartialTypeGuard<object, Partial<Record<K, V>>>; /** * Validate that a given object has all the given properties * * @param props - a MappedGuard of the object to be validated, i.e. an object that has the same properties as the * object being validated whose types are TypeGuards for the matching type on the original property. * * @public */ export declare const hasProperties: <V extends object>(props: MappedTypeGuard<V>) => PartialTypeGuard<object, V>; /** * Validates that a given object has a property of a given type. * * @public */ export declare const hasProperty: <K extends string, V>(property: K, value: TypeGuard<V>) => PartialTypeGuard<object, Record<K, V>>; /** * Validates that a given object has a string index signature. * * @param enforce - Whether to enforce that there is at least one property already set. Be careful setting this to * false, you will get some unexpected outputs, for instance arrays will have a string index signature. * * @public */ export declare const hasStringIndexSignature: <V>(value: TypeGuard<V>, enforce?: boolean) => PartialTypeGuard<object, Record<string, V>>; /** * Fluent Builder pattern for creating guards for interface types. * * @public */ export declare interface InterfaceBuilder<T extends object> { /** * Finalise and return the type guard which has been built. */ get: () => TypeGuard<T>; /** * Add a free-form type guard to this interface as a union. */ with: <V extends object>(ptv: PartialTypeGuard<object, V>) => InterfaceBuilder<T & V>; /** * Add a single property to the interface. * * @param key - The string key of the property. * @param ptv - The type guard for this property. */ withProperty: <K extends string, V>(key: K, ptv: TypeGuard<V>) => InterfaceBuilder<T & Record<K, V>>; /** * Add a single optional property to the interface. * * @param key - The string key of the property. * @param ptv - The type guard for this property. */ withOptionalProperty: <K extends string, V>(key: K, ptv: TypeGuard<V>) => InterfaceBuilder<T & Partial<Record<K, V>>>; /** * Add a string index signature to the interface. * * @param value - The type guard for values accessed by the index signature. * @param enforce - Whether to enforce that there is at least one property already set. Be careful setting this to * false, you will get some unexpected outputs, for instance arrays will have a string index signature. */ withStringIndexSignature: <V>(value: TypeGuard<V>, enforce?: boolean) => InterfaceBuilder<T & Record<string, V>>; /** * Add a numeric index signature to the interface. * * @param value - The type guard for values accessed by the index signature. * @param enforce - Whether to enforce that there is at least one property already set. Be careful setting this to * false, you will get some unexpected outputs, for instance arrays will have a string index signature. */ withNumericIndexSignature: <V>(value: TypeGuard<V>, enforce?: boolean) => InterfaceBuilder<T & Record<number, V>>; /** * Add many properties to the interface at once. * * @param props - A map of properties to guards to apply to the interface. */ withProperties: <V extends object>(props: MappedTypeGuard<V>) => InterfaceBuilder<T & V>; /** * Add many optional properties to the interface at once. * * @param props - A map of properties to guards to apply to the interface. */ withOptionalProperties: <V extends object>(props: MappedTypeGuard<V>) => InterfaceBuilder<T & Partial<V>>; } /** * A small class to help with constructing larger intersection checkers. * * @public */ export declare class IntersectionOf<B, T extends B> { private readonly ptt; constructor(ptt: PartialTypeGuard<B, T>); /** * Finalise and return the partial type guard for this builder. */ get(): PartialTypeGuard<B, T>; /** * Add a new option for this intersection. */ with<U extends B>(ptu: PartialTypeGuard<B, U>): IntersectionOf<B, T & U>; } /** * Helper for asserting nothing at all. * * Note: this is very rarely useful. You probably want isSet. isAny * allows null and undefined through as well - it matches TypeScripts type * and simply returns a static true because anything is an any. * * You can use isSet to validate that a value is non-null then let TypeScript * widen it back to any in your interface. * * @public */ export declare const isAny: TypeGuard<unknown>; /** * Validate if a value is an array of a specific type of value. * * @public */ export declare const isArray: <T>(valueCheck: TypeGuard<T>) => TypeGuard<T[]>; /** * Validate if a value is a boolean. * * @public */ export declare const isBoolean: TypeGuard<boolean>; /** * Alias for isFloat. * * @see isFloat() * @public */ export declare const isDouble: TypeGuard<number>; /** * Validates that a value is one of a set of values. * * @public */ export declare const isElementOf: { (): TypeGuard<never>; <T>(...ss: T[]): TypeGuard<T>; }; /** * Validate that an object has exactly the fields provided. * * @public */ export declare const isExactObject: <V extends object>(props: MappedTypeGuard<V>) => TypeGuard<V>; /** * Validate the value is a finite number. * * @public */ export declare const isFiniteNumber: TypeGuard<number>; /** * Validate the value is a number in the rawest sense. * * This check is exactly what the type system says on the tin. This value is a floating point value with all * the edge cases that entails. * * @public */ export declare const isFloat: TypeGuard<number>; /** * Validate the value is infinite. * * @public */ export declare const isInfinity: TypeGuard<number>; /** * Validates that a given object is an instance of a class. * * @public */ export declare const isInstance: <T extends object>(klass: abstract new (...args: never[]) => T) => TypeGuard<T>; /** * A small class to help with constructing interface guards. * * @public */ export declare class IsInterface implements InterfaceBuilder<object> { get(): TypeGuard<object>; with<V extends object>(ptv: PartialTypeGuard<object, V>): InterfaceBuilder<V>; withProperty<K extends string, V>(key: K, ptv: TypeGuard<V>): InterfaceBuilder<Record<K, V>>; withOptionalProperty<K extends string, V>(key: K, ptv: TypeGuard<V>): InterfaceBuilder<object & Partial<Record<K, V>>>; withStringIndexSignature<V>(value: TypeGuard<V>, enforce?: boolean): InterfaceBuilder<Record<string, V>>; withNumericIndexSignature<V>(value: TypeGuard<V>, enforce?: boolean): InterfaceBuilder<Record<number, V>>; withProperties<V extends object>(props: MappedTypeGuard<V>): InterfaceBuilder<object & V>; withOptionalProperties<V extends object>(props: MappedTypeGuard<V>): InterfaceBuilder<object & Partial<V>>; } /** * Check if a value is an intersection of two types. * * @public */ export declare const isIntersection: <B, T extends B, U extends B>(ptt: PartialTypeGuard<B, T>, ptu: PartialTypeGuard<B, U>) => PartialTypeGuard<B, T & U>; /** * Validate that an object has the fields provided. * * @public */ export declare const isLikeObject: <V extends object>(props: MappedTypeGuard<V>) => TypeGuard<V>; /** * Validates if a value is a given type or null or undefined. * * @public */ export declare const isMissing: <T>(tgt: TypeGuard<T>) => TypeGuard<T | undefined | null>; /** * Validates a value is exactly the NaN constant value. * * @public */ declare const isNaN_2: TypeGuard<number>; export { isNaN_2 as isNaN } /** * Helper for exhaustiveness checking. * * @public */ export declare const isNever: (n: never) => never; /** * Validate if a value is a non-empty array of a specific type of value. * * @public */ export declare const isNotEmptyList: <T>(valueCheck: TypeGuard<T>) => TypeGuard<[T, ...T[]]>; /** * Validate if a value is the constant null. * * @public */ export declare const isNull: TypeGuard<null>; /** * Validate if a value is a given type or null. * * @public */ export declare const isNullable: <T>(tgt: TypeGuard<T>) => TypeGuard<T | null>; /** * Validate if a value is a javascript number. * * @public */ export declare const isNumber: TypeGuard<number>; /** * Validates if a value is a valid part of a numeric enumeration. * * @param e - The enumeration to check * @param flags - Whether this is a flag style enumeration * * @public */ export declare const isNumericalEnumeration: <T extends Record<string | number, string | number>>(e: T, flags?: boolean) => TypeGuard<T>; /** * Validate if a value is an object. * * @public */ export declare const isObject: TypeGuard<object>; /** * Validate if a value is like an object. * * Specifically, this only checks typeof === "object" which includes * things that typescript has other primitives for like arrays. * * @public */ export declare const isObjectLike: TypeGuard<object>; /** * Validate if a value is optionally a given type. * * @public */ export declare const isOptional: <T>(tgt: TypeGuard<T>) => TypeGuard<T | undefined>; /** * Validate that a variable is an object with a single field. * * If you need multiple fields then use hasProperties. * * @public */ export declare const isRecord: <K extends string, V>(property: K, value: TypeGuard<V>) => TypeGuard<Record<K, V>>; /** * Validates if a value is not null and not undefined. * * @public */ export declare const isSet: <T = unknown>(obj: T) => obj is Diff<T, undefined | null>; /** * Validate if an object is a Set containing elements of a given type. * * @public */ export declare const isSetOf: <T>(tg: TypeGuard<T>) => (o: unknown) => o is Set<T>; /** * Validate if a value is a specific javascript number. * * @public */ export declare const isSingletonNumber: <T extends number>(v: T) => TypeGuard<T>; /** * Validate if a value is one of a set of specific numbers. * * @public */ export declare const isSingletonNumberUnion: { (): TypeGuard<never>; <T extends number>(...ss: T[]): TypeGuard<T>; }; /** * Validate if a value is a specific string. * * @public */ export declare const isSingletonString: <T extends string>(v: T) => TypeGuard<T>; /** * Validate if a value is one of a set of specific strings. * * @public */ export declare const isSingletonStringUnion: { (): TypeGuard<never>; <T extends string>(...ss: T[]): TypeGuard<T>; }; /** * Validate if a value is a string. * * @public */ export declare const isString: TypeGuard<string>; /** * Validates if a value is a valid part of a string enumeration. * * @param e - The enumeration to check * * @public */ export declare const isStringEnumeration: <T extends Record<string, string>>(e: T) => TypeGuard<T>; /** * Validate if a value is the constant undefined. * * @public */ export declare const isUndefined: TypeGuard<undefined>; /** * Check if a value is a union of two types. * * @public */ export declare const isUnion: <B, T extends B, U extends B>(ptt: PartialTypeGuard<B, T>, ptu: PartialTypeGuard<B, U>) => PartialTypeGuard<B, T | U>; /** * Alias for isAny. * * @see isAny * @public */ export declare const isUnknown: TypeGuard<unknown>; /** * An object of type guards based on the input type. * * @public */ export declare type MappedTypeGuard<T> = { [P in keyof T]: TypeGuard<T[P]>; }; /** * Narrow the type of elements inside an array. * * @public */ export declare const narrowArray: <T, U extends T>(pt: PartialTypeGuard<T, U>) => PartialTypeGuard<T[], U[]>; /** * Narrow the type of a value. * * @public * @deprecated Use combine instead, this alias is poorly named. */ export declare const narrowValue: <T, U extends T, V extends U>(ptt: PartialTypeGuard<T, U>, ptu: PartialTypeGuard<U, V>) => PartialTypeGuard<T, V>; /** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * A partial type guard that can take a value of one type and determine if it is also a valid value of a subtype. * * @public */ export declare type PartialTypeGuard<T, U extends T> = (value: T) => value is U; /** * A full type guard that can guard any value and determine if it is valid. * * @public */ export declare type TypeGuard<T> = PartialTypeGuard<unknown, T>; /** * A small class to help with constructing larger union checkers. * * @public */ export declare class UnionOf<B, T extends B> { private readonly ptt; constructor(ptt: PartialTypeGuard<B, T>); /** * Finalise and return the partial type guard for this builder. */ get(): PartialTypeGuard<B, T>; /** * Add a new option for this union. */ with<U extends B>(ptv: PartialTypeGuard<B, U>): UnionOf<B, T | U>; } export { }