typesafe-ts
Version:
TypeScript utilities for type-safe error handling and optional values
153 lines • 5.21 kB
TypeScript
/**
* Utility type to check if two types are exactly equal.
*
* This performs a strict equality check that distinguishes between `any`, `unknown`, `never`,
* and other types that might seem similar but are actually different.
*
* @template Left - The first type to compare
* @template Right - The second type to compare
* @returns `true` if the types are exactly equal, `false` otherwise
*
* @example
* Basic type equality:
* ```ts
* type Test1 = Equal<string, string>; // true
* type Test2 = Equal<string, number>; // false
* type Test3 = Equal<string, any>; // false
* type Test4 = Equal<unknown, any>; // false
* ```
*
* @example
* Structural equality:
* ```ts
* type User = { name: string; age: number };
* type Person = { name: string; age: number };
* type Employee = { name: string; age: number; role: string };
*
* type Test1 = Equal<User, Person>; // true (same structure)
* type Test2 = Equal<User, Employee>; // false (different structure)
* ```
*
* @example
* Union type equality:
* ```ts
* type Test1 = Equal<1 | 2 | 3, 3 | 2 | 1>; // true (order doesn't matter)
* type Test2 = Equal<true | false, boolean>; // true (equivalent)
* type Test3 = Equal<string | number, any>; // false (any is not a union)
* ```
*
* @example
* Use with Assert for compile-time type checking:
* ```ts
* import { Assert, type Check } from "typesafe-ts/assert";
*
* type ApiResponse = { data: string };
* type ExpectedShape = { data: string };
*
* // ✅ Passes - types are equal
* Assert<Check.Equal<ApiResponse, ExpectedShape>, "API response shape mismatch">();
*
* // ❌ Fails - types are different
* Assert<Check.Equal<ApiResponse, { data: number }>, "Wrong data type">();
* ```
*/
export type Equal<Left, Right> = (<T>() => T extends Left ? 1 : 2) extends <T>() => T extends Right ? 1 : 2 ? true : false;
/**
* Utility type to check if a type is exactly `true`.
*
* @template T - The type to check
* @returns `true` if T is exactly the `true` type, `false` otherwise
*
* @example
* ```ts
* type Test1 = True<true>; // true
* type Test2 = True<false>; // false
* type Test3 = True<boolean>; // false
* type Test4 = True<1>; // false (truthy but not true)
* type Test5 = True<never>; // false
* ```
*/
export type True<T> = Equal<T, true>;
/**
* Utility type to check if a type is exactly `false`.
*
* @template T - The type to check
* @returns `true` if T is exactly the `false` type, `false` otherwise
*
* @example
* ```ts
* type Test1 = False<false>; // true
* type Test2 = False<true>; // false
* type Test3 = False<boolean>; // false
* type Test4 = False<0>; // false (falsy but not false)
* type Test5 = False<never>; // false
* ```
*/
export type False<T> = Equal<T, false>;
/**
* Utility type to check if one type extends another (subtype relationship).
* Equivalent to `SubType extends SuperType ? true : false`.
*
* @template SubType - The potentially narrower type
* @template SuperType - The potentially broader type
* @returns `true` if SubType extends SuperType, `false` otherwise
*
* @example
* ```ts
* type Test1 = Extends<string, any>; // true
* type Test2 = Extends<"hello", string>; // true (literal extends base)
* type Test3 = Extends<string, number>; // false
* type Test4 = Extends<never, string>; // true (never extends everything)
* type Test5 = Extends<{a: 1, b: 2}, {a: 1}>; // true (subtype extends supertype)
* ```
*/
export type Extends<SubType, SuperType> = SubType extends SuperType ? true : false;
/**
* Utility type to check if a type is exactly `never`.
*
* @template T - The type to check
* @returns `true` if T is exactly the `never` type, `false` otherwise
*
* @example
* ```ts
* type Test1 = IsNever<never>; // true
* type Test2 = IsNever<undefined>; // false
* type Test3 = IsNever<null>; // false
* type Test4 = IsNever<void>; // false
* type Test5 = IsNever<unknown>; // false
* ```
*/
export type IsNever<T> = Equal<T, never>;
/**
* Utility type to check if a type is exactly `any`.
*
* @template T - The type to check
* @returns `true` if T is exactly the `any` type, `false` otherwise
*
* @example
* ```ts
* type Test1 = IsAny<any>; // true
* type Test2 = IsAny<unknown>; // false
* type Test3 = IsAny<never>; // false
* type Test4 = IsAny<{}>; // false
* type Test5 = IsAny<object>; // false
* ```
*/
export type IsAny<T> = Equal<T, any>;
/**
* Utility type to check if a type is exactly `unknown`.
*
* @template T - The type to check
* @returns `true` if T is exactly the `unknown` type, `false` otherwise
*
* @example
* ```ts
* type Test1 = IsUnknown<unknown>; // true
* type Test2 = IsUnknown<any>; // false
* type Test3 = IsUnknown<never>; // false
* type Test4 = IsUnknown<{}>; // false
* type Test5 = IsUnknown<object>; // false
* ```
*/
export type IsUnknown<T> = Equal<T, unknown>;
//# sourceMappingURL=check.d.ts.map