### Install expect-type using npm Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Command to install expect-type as a development dependency. ```bash npm install --save-dev expect-type ``` -------------------------------- ### Usage Patterns - Class and Constructor Testing Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing class constructors and instances. ```APIDOC ## Usage Pattern: Class and Constructor Testing ### Description Demonstrates how to test types related to classes, including their constructors and instances. ### Example ```typescript import { expectTypeOf } from 'expect-type'; class Person { constructor(public name: string, public age: number) {} greet(): string { return `Hello, ${this.name}`; } } // Testing the constructor parameters expectTypeOf().constructorParameters.toEqualTypeOf<[name: string, age: number]>(); // Testing the instance type expectTypeOf().toEqualTypeOf<{ name: string; age: number; greet(): string; }>(); // Testing instance properties expectTypeOf().toHaveProperty('name'); expectTypeOf().toHaveProperty('greet'); // Testing the return type of a method expectTypeOf().instance.toHaveProperty('greet').returns.toEqualTypeOf(); ``` ``` -------------------------------- ### Example Usage of IsUselessOverloadInfo Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Demonstrates the usage of `IsUselessOverloadInfo` with both a placeholder overload and a real overload. ```typescript type Placeholder = (...args: unknown[]) => unknown IsUselessOverloadInfo // true type RealOverload = (x: number) => string IsUselessOverloadInfo // false ``` -------------------------------- ### Usage Patterns - Function and Overload Testing Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing function signatures and overloads. ```APIDOC ## Usage Pattern: Function and Overload Testing ### Description Shows how to test function types, including their parameters, return types, and handling of overloads. ### Example ```typescript import { expectTypeOf } from 'expect-type'; // Single function signature type Add = (a: number, b: number) => number; expectTypeOf().toBeCallableWith(1, 2); expectTypeOf().returns.toEqualTypeOf(); // Function with overloads function process(input: string): string; function process(input: number): number; function process(input: string | number): string | number { return input; } expectTypeOf().parameter(0).toEqualTypeOf(); expectTypeOf().returns.toEqualTypeOf(); // Testing specific overload parameters (requires advanced usage or specific utility) // For example, checking the first overload: // expectTypeOf().overload(0).parameters.toEqualTypeOf<[string]>(); ``` ``` -------------------------------- ### Usage Patterns - Promise and Array Handling Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing types related to Promises and Arrays. ```APIDOC ## Usage Pattern: Promise and Array Handling ### Description Shows how to use `expect-type` to assert the types contained within Promises and Arrays. ### Example ```typescript import { expectTypeOf } from 'expect-type'; // Promise handling type PromiseOfNumbers = Promise; expectTypeOf().resolves.toEqualTypeOf(); expectTypeOf().resolves.items.toEqualTypeOf(); // Array handling type StringArray = string[]; expectTypeOf().items.toEqualTypeOf(); type NestedArray = number[][]; expectTypeOf().items.toEqualTypeOf(); expectTypeOf().items.items.toEqualTypeOf(); // Tuple handling type MyTuple = [string, number]; expectTypeOf().items.toEqualTypeOf(); // Note: .items on tuple gives union of elements expectTypeOf().toEqualTypeOf<[string, number]>(); ``` ``` -------------------------------- ### Usage Patterns - Generic Function Testing Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing generic functions. ```APIDOC ## Usage Pattern: Generic Function Testing ### Description Demonstrates how to assert types within generic functions. ### Example ```typescript import { expectTypeOf } from 'expect-type'; function identity(arg: T): T { return arg; } // Asserting the type parameter T within the function context expectTypeOf().parameter(0).toEqualTypeOf(); // Default generic type // When called, T is inferred const strIdentity = identity; expectTypeOf().parameter(0).toEqualTypeOf(); expectTypeOf().returns.toEqualTypeOf(); // Limitation workaround example (as mentioned in limitations section) // If you need to assert specific generic constraints, you might use .map() or other utilities. ``` ``` -------------------------------- ### Usage Patterns - Property Checking and Modification Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of checking and manipulating object properties. ```APIDOC ## Usage Pattern: Property Checking and Modification ### Description Covers testing for the existence of properties and using `pick`/`omit` for type modification. ### Example ```typescript import { expectTypeOf } from 'expect-type'; type Config = { host: string; port: number; timeout?: number; protocol: 'http' | 'https'; }; // Checking for properties expectTypeOf().toHaveProperty('host'); expectTypeOf().toHaveProperty('timeout'); // Optional property expectTypeOf().not.toHaveProperty('path'); // Using pick and omit expectTypeOf().pick<'host' | 'port'>().toEqualTypeOf<{ host: string; port: number; }>(); expectTypeOf().omit<'timeout' | 'protocol'>().toEqualTypeOf<{ host: string; port: number; }>(); ``` ``` -------------------------------- ### Usage Patterns - Object Type Testing Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing object types. ```APIDOC ## Usage Pattern: Object Type Testing ### Description Demonstrates how to use `expect-type` to assert the structure and properties of object types. ### Example ```typescript import { expectTypeOf } from 'expect-type'; type UserProfile = { id: number; username: string; isActive: boolean; roles?: string[]; }; expectTypeOf().toEqualTypeOf<{ id: number; username: string; isActive: boolean; roles?: string[]; }>(); expectTypeOf().toHaveProperty('username'); expectTypeOf().not.toHaveProperty('email'); expectTypeOf().toHaveProperty('roles'); // Optional property expectTypeOf().pick<'id' | 'username'>().toEqualTypeOf<{ id: number; username: string; }>(); ``` ``` -------------------------------- ### Usage Patterns - Type Guards and Assertions Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Conceptual examples of using type guards and assertions. ```APIDOC ## Usage Pattern: Type Guards and Assertions ### Description While `expect-type` is primarily for compile-time checks, it can be used conceptually to document or verify the expected behavior of type guards and assertions. ### Example ```typescript import { expectTypeOf } from 'expect-type'; // Assume a type guard function function isString(value: unknown): value is string { return typeof value === 'string'; } // Using expect-type to assert the signature of the type guard expectTypeOf().parameter(0).toEqualTypeOf(); expectTypeOf().returns.toEqualTypeOf(); // This would resolve to false, demonstrating the limitation of compile-time checks for runtime guards. // A more direct assertion on the return type if it were simpler: // expectTypeOf().returns.toEqualTypeOf(); // This would pass if the guard only returned boolean // Asserting a type assertion function (e.g., a custom assert function) type AssertIsString = (value: unknown) => asserts value is string; expectTypeOf().parameter(0).toEqualTypeOf(); ``` *Note: `expect-type` operates at compile time. Asserting the runtime behavior or precise conditional return types of type guards can be complex and may require different approaches or deeper dives into the library's advanced features.* ``` -------------------------------- ### Example: ConstructorOverloadParameters Usage Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Shows how `ConstructorOverloadParameters` extracts the parameter types from a class with multiple constructor overloads, resulting in a union of parameter tuples. ```typescript class Logger { constructor() constructor(level: 'debug' | 'info' | 'error') constructor(level?: string) {} } type ConstructorParams = ConstructorOverloadParameters // Result: [] | ['debug' | 'info' | 'error'] ``` -------------------------------- ### Example: OverloadReturnTypes Usage Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Demonstrates how `OverloadReturnTypes` correctly extracts a union of return types from a function with string and File overloads. ```typescript type ParseMultiple = { (input: string): string[] (input: File): Promise } type AllReturns = OverloadReturnTypes // Result: string[] | Promise ``` -------------------------------- ### Usage Patterns - Type Introspection Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of using introspection methods. ```APIDOC ## Usage Pattern: Type Introspection ### Description Demonstrates using methods like `guards` and `asserts` for introspective type checks (conceptual). ### Example ```typescript import { expectTypeOf } from 'expect-type'; // Conceptual example for guards // type MaybeString = string | null; // expectTypeOf().guards.isString().toBeTrue(); // Asserting that the 'isString' guard would pass for string // expectTypeOf().guards.isString().toBeFalse(); // Asserting that the 'isString' guard would fail for null // Conceptual example for asserts // type MyType = { prop: string }; // expectTypeOf().asserts.isObject(); // Asserting that the type is an object ``` *Note: These are illustrative. The actual implementation and usage of `guards` and `asserts` might be more nuanced and depend on the specific context within the library's design.* ``` -------------------------------- ### Usage Patterns - Union Type Narrowing Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Examples of testing type narrowing with unions. ```APIDOC ## Usage Pattern: Union Type Narrowing ### Description Illustrates how to test type narrowing scenarios involving union types. ### Example ```typescript import { expectTypeOf } from 'expect-type'; type StringOrNumber = string | number; // Asserting the union type itself expectTypeOf().toEqualTypeOf(); // Using extract/exclude to test narrowed types expectTypeOf().extract().toEqualTypeOf(); expectTypeOf().exclude().toEqualTypeOf(); // Testing within a conditional type type GetType = T extends string ? 'string' : 'other'; expectTypeOf>().toEqualTypeOf<'string'>(); expectTypeOf>().toEqualTypeOf<'other'>(); ``` ``` -------------------------------- ### Example Usage of TSPost53OverloadsInfoUnion Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Shows how `TSPost53OverloadsInfoUnion` extracts overloads from a function type with multiple signatures. ```typescript type Add = { (a: number, b: number): number (a: string, b: string): string } type Overloads = TSPost53OverloadsInfoUnion // Result: ((a: number, b: number) => number) | ((a: string, b: string) => string) ``` -------------------------------- ### Assertions on Object Properties Source: https://github.com/mmkal/expect-type/blob/main/README.md Provides examples of checking for the existence and types of object properties using .toHaveProperty. ```typescript const obj = {a: 1, b: ''} // check that properties exist (or don't) with `.toHaveProperty` expectTypeOf(obj).toHaveProperty('a') expectTypeOf(obj).not.toHaveProperty('c') // check types of properties expectTypeOf(obj).toHaveProperty('a').toBeNumber() expectTypeOf(obj).toHaveProperty('b').toBeString() expectTypeOf(obj).toHaveProperty('a').not.toBeString() ``` -------------------------------- ### Distinguish type relationships with .toExtend, .toMatchObjectType, and .toEqualTypeOf Source: https://github.com/mmkal/expect-type/blob/main/README.md This example illustrates the differences between .toExtend, .toMatchObjectType, and .toEqualTypeOf, particularly for subtype relationships. ```typescript type Fruit = {type: 'Fruit'; edible: boolean} type Apple = {type: 'Fruit'; name: 'Apple'; edible: true} expectTypeOf().toExtend() // @ts-expect-error - the `editable` property isn't an exact match. In `Apple`, it's `true`, which extends `boolean`, but they're not identical. expectTypeOf().toMatchObjectType() // @ts-expect-error - Apple is not an identical type to Fruit, it's a subtype expectTypeOf().toEqualTypeOf() // @ts-expect-error - Apple is a Fruit, but not vice versa expectTypeOf().toExtend() ``` -------------------------------- ### Example Usage of TSPre53OverloadsInfoUnion Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Demonstrates the `TSPre53OverloadsInfoUnion` for filtering useless overloads automatically added by older TypeScript versions. ```typescript type Overloads = TSPre53OverloadsInfoUnion // Automatically filters useless overloads added by older TypeScript ``` -------------------------------- ### More .not Examples Source: https://github.com/mmkal/expect-type/blob/main/README.md Demonstrate negations using `.not` to assert that a type does not match certain characteristics, such as being unknown, any, never, null, or undefined. ```typescript expectTypeOf(1).not.toBeUnknown() expectTypeOf(1).not.toBeAny() expectTypeOf(1).not.toBeNever() expectTypeOf(1).not.toBeNull() expectTypeOf(1).not.toBeUndefined() expectTypeOf(1).not.toBeNullable() expectTypeOf(1).not.toBeBigInt() ``` -------------------------------- ### Type Mismatch Error Example Source: https://github.com/mmkal/expect-type/blob/main/README.md Demonstrates a type mismatch using .toEqualTypeOf. The error message highlights the expected vs. actual types for a property. ```typescript expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() ``` -------------------------------- ### Example Usage of Tuplify Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Illustrates the `Tuplify` utility, which wraps a union type in a tuple to prevent distribution. ```typescript type U = 'a' | 'b' | 'c' type T = Tuplify // ['a' | 'b' | 'c'] ``` -------------------------------- ### Type Mismatch Error Message Example Source: https://github.com/mmkal/expect-type/blob/main/README.md Illustrates the format of a TypeScript error message for a type mismatch, showing how to interpret expected and actual types. ```typescript test/test.ts:999:999 - error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: \"Expected: string, Actual: number\"; }'. Types of property 'a' are incompatible. Type 'string' is not assignable to type '\"Expected: string, Actual: number\"'. 999 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() ``` -------------------------------- ### Example Usage of NominalType Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/branding-and-deep-inspection.md Demonstrates how `NominalType` identifies `Date` as a nominal type based on `DeepBrandOptionsDefaults`, while a plain object is not recognized as nominal. ```typescript type DateNominal = NominalType // Result: 'Date' type ObjectNominal = NominalType<{a: string}, DeepBrandOptionsDefaults> // Result: never ``` -------------------------------- ### Get Constructor Overload Parameters Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/types.md A placeholder type for extracting a union of parameter tuples for all constructor overloads. ```typescript export type ConstructorOverloadParameters ``` -------------------------------- ### Convert Tuple to Record Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/type-utility-functions.md Converts a tuple into a record with numeric string keys. The example shows the conversion from a tuple to a record with numeric string keys. ```typescript export type TupleToRecord = { [K in keyof T as `${Extract}`]: T[K] } ``` -------------------------------- ### Type Assertions for Function Overloads Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Shows how to assert types for functions with multiple overloads, including getting all overloads as a union and narrowing to a specific overload. ```typescript type Parser = { (input: string): any[] (input: File): Promise } // Get all overloads as union expectTypeOf().parameters.toEqualTypeOf<[string] | [File]>() // Narrow to specific overload expectTypeOf() .toBeCallableWith({} as File) .returns.toEqualTypeOf>() ``` -------------------------------- ### Using expect-type with Vitest Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Example of integrating expect-type assertions within Vitest test suites. Note that expectTypeOf can also be imported directly from vitest. ```typescript import { describe, it } from 'vitest' import { expectTypeOf } from 'vitest' // Also available from vitest! describe('types', () => { it('should have correct types', () => { expectTypeOf([1, 2, 3]).items.toBeNumber() }) }) ``` -------------------------------- ### Example: Asserting a function does not return 'any' Source: https://github.com/mmkal/expect-type/blob/main/README.md This snippet demonstrates how to use `expectTypeOf` to assert that a function's return type is not `any`. This is useful for preventing overly permissive return types that could lead to runtime errors. ```typescript import { expectTypeOf } from "expect-type"; // Assume parseFile is a function that might return 'any' // const parseFile = (filename: string) => JSON.parse(readFileSync(filename).toString()); // Example assertion: // expectTypeOf(parseFile).returns.not.toBeAny(); ``` -------------------------------- ### Primitive Type Mismatch Error Message Example Source: https://github.com/mmkal/expect-type/blob/main/README.md Presents the error message for a primitive type mismatch, where 'Type 'ExpectString' has no call signatures' indicates the failure. ```typescript test/test.ts:999:999 - error TS2349: This expression is not callable. Type 'ExpectString' has no call signatures. 999 expectTypeOf(1).toBeString() ~~~~~~~~~~ ``` -------------------------------- ### Comparing Concrete Types with .toEqualTypeOf Source: https://github.com/mmkal/expect-type/blob/main/README.md Example of using .toEqualTypeOf with concrete types, which can lead to less helpful error messages compared to using type arguments. ```typescript expectTypeOf({a: 1}).toEqualTypeOf({a: ''}) ``` -------------------------------- ### Primitive Type Mismatch Error Example Source: https://github.com/mmkal/expect-type/blob/main/README.md Shows a type mismatch when asserting a primitive type using methods like .toBeString. The error indicates a type that has no call signatures. ```typescript expectTypeOf(1).toBeString() ``` -------------------------------- ### Get Useful Keys for Arrays and Objects Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/type-utility-functions.md Gets "useful" keys for a type: numeric indices for arrays, all keys for objects and tuples. This utility helps in accessing elements or properties generically. ```typescript export type UsefulKeys = T extends any[] ? {[K in keyof T]: K}[number] : keyof T ``` ```typescript type ObjKeys = UsefulKeys<{a: string; b: number}> // 'a' | 'b' type ArrayKeys = UsefulKeys<['x', 'y']> // '0' | '1' type StringArrayKeys = UsefulKeys // number ``` -------------------------------- ### LastOf Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/type-utility-functions.md Gets the last element of a union. Used internally by `UnionToTuple`. ```typescript export type LastOf = UnionToIntersection Union : never> extends () => infer R ? R : never ``` ```typescript type Last = LastOf<'a' | 'b' | 'c'> // 'c' ``` -------------------------------- ### View Specific Document Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/COMPLETION-SUMMARY.md Use this command to view the content of a specific documentation file, such as the API reference for assertions. ```bash # View specific document cat output/api-reference-assertions.md ``` -------------------------------- ### Search for Specific Method Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/COMPLETION-SUMMARY.md Use this command to search for a specific method within the expect-type documentation files. ```bash # Search for specific method grep -r "toEqualTypeOf" output/ ``` -------------------------------- ### View Table of Contents Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/COMPLETION-SUMMARY.md Use this command to view the table of contents for the expect-type documentation. ```bash # View table of contents cat output/README.md ``` -------------------------------- ### Picking Properties with .pick Source: https://github.com/mmkal/expect-type/blob/main/README.md Shows how to use the .pick method to select specific properties from a type. ```typescript type Person = {name: string; age: number} expectTypeOf().pick<'name'>().toEqualTypeOf<{name: string}>() ``` -------------------------------- ### Basic Type Assertions with expect-type Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Demonstrates basic type checking, including exact type matching, parameter and return type checks, object property assertions, and negation. ```typescript import { expectTypeOf } from 'expect-type' // Test exact type match expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>() // Test type properties const fn = (x: string) => x.length expectTypeOf(fn).parameter(0).toBeString() expectTypeOf(fn).returns.toBeNumber() // Test object properties expectTypeOf({ name: 'Alice', age: 30 }) .toHaveProperty('name') .toBeString() // Negate assertions expectTypeOf({ a: 1 }).not.toExtend<{ b: number }>() ``` -------------------------------- ### Limitations & Workarounds - Any Detection Challenges Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Explains the difficulties in detecting and asserting `any` types. ```APIDOC ## Limitation: `any` Detection Challenges ### Description TypeScript's `any` type bypasses type checking, making it inherently difficult to assert its presence or absence reliably using static analysis alone. ### Limitation Details - `any` is assignable to everything and everything is assignable to `any`. - Assertions like `toEqualTypeOf()` might behave unexpectedly or require specific handling. - `expectTypeOf().toBeAny()` is the primary method to assert if a type `T` is `any`. ### Workaround - **Use `toBeAny()`**: This is the dedicated method for asserting `any` types. - **Be explicit**: When `any` is involved, be very clear about whether you are asserting its presence or asserting that a type is *not* `any` (using `.not.toBeAny()`). ### Example ```typescript import { expectTypeOf } from 'expect-type'; let value: any; expectTypeOf().toBeAny(); let str: string; expectTypeOf().not.toBeAny(); // Caution: This might not behave as expected in all scenarios due to 'any's nature // expectTypeOf().toEqualTypeOf(); // Likely fails ``` ``` -------------------------------- ### Get Overload This Parameter Types Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/types.md A placeholder type for extracting a union of `this` parameter types for all overloads of a function. ```typescript export type OverloadThisParameterTypes ``` -------------------------------- ### Get Overload Return Types Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/types.md A placeholder type for extracting a union of return types for all overloads of a function. ```typescript export type OverloadReturnTypes ``` -------------------------------- ### Function Parameter and Return Type Assertions Source: https://github.com/mmkal/expect-type/blob/main/README.md Shows how to assert the parameters and return types of functions using .parameters and .returns. ```typescript type NoParam = () => void type HasParam = (s: string) => void expectTypeOf().parameters.toEqualTypeOf<[]>() expectTypeOf().returns.toBeVoid() expectTypeOf().parameters.toEqualTypeOf<[string]>() expectTypeOf().returns.toBeVoid() ``` -------------------------------- ### Fail .toEqualTypeOf on excess properties Source: https://github.com/mmkal/expect-type/blob/main/README.md This example shows that .toEqualTypeOf will fail if the object has properties not present in the expected type. ```typescript // @ts-expect-error expectTypeOf({a: 1, b: 1}).toEqualTypeOf<{a: number}>() ``` -------------------------------- ### Limitations & Workarounds - Generic Functions with toBeCallableWith() Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Explains issues with `toBeCallableWith()` on generic functions and provides a workaround. ```APIDOC ## Limitation: Generic Functions with `toBeCallableWith()` ### Description Asserting the exact parameter types of a generic function using `toBeCallableWith()` can be tricky because the generic type parameter `T` is often inferred as `unknown` by default. ### Limitation Details - When `expectTypeOf()` is used, `T` might be treated as `unknown` if not explicitly provided or inferred correctly. - `toBeCallableWith(expectedArg)` might fail if `expectedArg` doesn't match `unknown`. ### Workaround - **Explicitly provide generic type**: When asserting the function type itself, you might need to provide the generic type argument if possible, or assert against the expected inferred type. - **Use `.map()` or other utilities**: Sometimes, mapping the generic function type or its parameters can help in asserting the structure. ### Example (Conceptual Workaround using `.map()`) ```typescript import { expectTypeOf } from 'expect-type'; function processItem(item: T): T { return item; } // Direct assertion might be problematic if T is inferred as unknown // expectTypeOf().toBeCallableWith(123); // Might fail // Using .map() to inspect parameters (simplified example) // This requires understanding how .map() interacts with generic signatures. // A more robust solution might involve asserting the type after it's been used: const processedNumber = processItem(123); expectTypeOf().parameter(0).toEqualTypeOf(); // Asserting after inference expectTypeOf().returns.toEqualTypeOf(); ``` ``` -------------------------------- ### Limitations & Workarounds - Optional vs Undefined Distinction Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Explains the nuances between optional properties and `undefined`. ```APIDOC ## Limitation: Optional vs Undefined Distinction ### Description Understanding the difference between an optional property (`prop?: type`) and a property that is explicitly `undefined` (`prop: undefined`) is crucial for accurate type assertions. ### Limitation Details - An optional property `prop?: T` is equivalent to `prop: T | undefined`. - Asserting the presence or absence of optional properties requires careful use of `toHaveProperty` and checking against `undefined`. ### Workaround - **Use `toHaveProperty`**: To check if a property exists (even if optional). - **Check type with `undefined`**: To assert that an optional property's type includes `undefined`. ### Example ```typescript import { expectTypeOf } from 'expect-type'; type MyType = { requiredProp: string; optionalProp?: number; explicitlyUndefinedProp: undefined; }; // Asserting required property expectTypeOf().toHaveProperty('requiredProp'); expectTypeOf().requiredProp.toEqualTypeOf(); // Asserting optional property expectTypeOf().toHaveProperty('optionalProp'); // Property exists expectTypeOf().optionalProp.toEqualTypeOf(); // Type includes undefined // Asserting explicitly undefined property expectTypeOf().toHaveProperty('explicitlyUndefinedProp'); expectTypeOf().explicitlyUndefinedProp.toEqualTypeOf(); ``` ``` -------------------------------- ### Using .toBeAny() vs .branded.inspect() Source: https://github.com/mmkal/expect-type/blob/main/README.md Distinguish between `.toBeAny()` for specific property checks and `.branded.inspect()` for discovering hidden `any` types across an entire type structure. ```typescript const bad = (metadata: string) => ({ name: 'Bob', meta: { parsed: JSON.parse(metadata), // whoops, any! }, }) // `.toBeAny()`: you already know which property to check. expectTypeOf(bad).returns.toHaveProperty('meta').toHaveProperty('parsed').toBeAny() // `.branded.inspect()`: surface _any_ `any` hiding anywhere in the (possibly huge) type, without knowing where to look. expectTypeOf(bad).returns.branded.inspect({ foundProps: { '.meta.parsed': 'any', }, }) ``` -------------------------------- ### Get Overload Parameters Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/types.md Extracts a union of parameter tuples for all overloads of a given function type. Useful for analyzing function signatures. ```typescript export type OverloadParameters = OverloadsInfoUnion extends InferFunctionType ? Parameters : never ``` ```typescript type Fn = { (x: number): number (x: string): string } OverloadParameters // [number] | [string] ``` -------------------------------- ### Deep Type Inspection with expect-type Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Example of using `inspect` to find hidden `any` or `never` types within a complex type structure. ```typescript // Find all hidden any/never types expectTypeOf().branded.inspect({ foundProps: { '.deeply.nested.field': 'any' } }) ``` -------------------------------- ### Import expectTypeOf Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/api-reference-main.md Import the primary function from the expect-type library. ```typescript import { expectTypeOf } from 'expect-type' ``` -------------------------------- ### Assertion Function Validation Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Validate assertion functions to ensure they correctly narrow down types. This example checks an assertion function that expects a string. ```typescript function assertEmail(v: any): asserts v is string { if (!v.includes('@')) throw new Error('Invalid') } expectTypeOf(assertEmail).asserts.toBeString() ``` -------------------------------- ### TypeScript Overload Handling (Pre-5.3) Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/limitations-and-workarounds.md Demonstrates the incorrect overload extraction in TypeScript versions before 5.3 due to a bug, and the correct handling with OverloadParameters. ```typescript type Factorize = { (...args: unknown[]): unknown // Added by TS bug (input: number): number[] (input: bigint): bigint[] } // On TS <5.3: // Parameters // [unknown] (WRONG - just the useless overload!) // With OverloadParameters: // OverloadParameters // [number] | [bigint] (CORRECT - filtered) ``` -------------------------------- ### Creating a Type with Optional Properties using Partial Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/limitations-and-workarounds.md Shows how to use the `Partial` utility type to create a type where all properties are optional, matching the behavior of `{a?: string; b?: number}`. ```typescript type PartialUser = Partial<{a: string; b: number}> // expectTypeOf().toEqualTypeOf<{a?: string; b?: number}>() ``` -------------------------------- ### Limitations & Workarounds - Summary Workaround Table Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt A conceptual table summarizing common workarounds for limitations. ```APIDOC ## Workaround Summary Table ### Description This table provides a quick reference for common limitations and their suggested workarounds. | Limitation | Workaround | |---------------------------------|----------------------------------------------------------------------------| | Intersection Types | Simplify with type aliases, use `.pick`/`.omit`, ensure correct branding. | | Deeply Nested Types | Refactor types, use `.map()` cautiously, check library for deep utilities. | | Generic Funcs + `toBeCallableWith` | Explicit generic args, assert after inference, use `.map()` or union utilities. | | `this` Parameter Constraint | Use `.thisParameter` accessor, assert instance types. | | Union Type Distribution | Use `extract`/`exclude`, `TuplifyUnion`/`UnionToTuple` for overloads. | | 10+ Overloads | Group overloads, use union types for common params/returns, focus on key ones. | | TS Version Specific Issues | Update TS, check compatibility notes, isolate issues in different versions. | | Optional vs Undefined | Use `toHaveProperty`, check types including `| undefined`. | | Readonly Properties | Use `ReadonlyKeys`, assert against `readonly` types. | | `.map()` with Null/Undefined | Handle null/undefined explicitly, test intermediate types. | | `any` Detection | Use `toBeAny()` and `.not.toBeAny()`. Be explicit. | | Compilation Performance | Use assertions selectively, simplify, profile, consider runtime checks. | *Note: This table is a summary. Refer to individual limitation sections for detailed explanations and examples.* ``` -------------------------------- ### Limitations & Workarounds - 10+ Overload Limitation Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Discusses the limitation on the number of function overloads and suggests solutions. ```APIDOC ## Limitation: 10+ Overload Limitation ### Description TypeScript itself has a limit (often around 10) on the number of overloads that can be defined for a single function. `expect-type` reflects this limitation. ### Limitation Details - Asserting functions with more than the supported number of overloads might lead to errors or incomplete type information. - The library might not be able to accurately represent or assert all overloads beyond this limit. ### Workaround - **Grouping/Abstraction**: If possible, refactor the function to reduce the number of distinct overloads, perhaps by using more general types or conditional logic within a single signature. - **Use `toBeCallableWith()` with Union Types**: Assert the common parameters and return types using union types if the overloads share similarities. - **Focus on Key Overloads**: If not all overloads are critical for type checking, focus assertions on the most important ones. ### Example (Conceptual) ```typescript import { expectTypeOf } from 'expect-type'; // Assume a function with many overloads (exceeding TS limit for illustration) // function complexFunc(arg: 1): string; // ... (many more overloads) // Asserting the common return type // expectTypeOf().returns.toEqualTypeOf(); // Asserting parameters for a specific overload might require filtering or specific utilities. ``` ``` -------------------------------- ### TypeScript Assertion Failure Example Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Demonstrates a typical TypeScript compiler error when an expectTypeOf assertion fails. The error message provides details on the expected and actual types. ```typescript expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() // error TS2344: Type '{ a: string; }' does not satisfy the constraint // '{ a: "Expected: string, Actual: number"; }' ``` -------------------------------- ### Using OverloadParameters in toBeCallableWith() Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Demonstrates how `toBeCallableWith()` uses `OverloadParameters<>` to extract parameter combinations, check argument compatibility with any overload, and narrow the function type. ```typescript type Parser = { (input: string): any[] (input: string, format: 'json' | 'csv'): any[] (input: File): Promise } // First call narrows based on args expectTypeOf() .toBeCallableWith('{"a":1}', 'json') // Narrows to second overload .returns.toEqualTypeOf() // Non-promise return type ``` -------------------------------- ### Type Assertion Failure Example Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/api-reference-main.md Illustrates a TypeScript compiler error when a type assertion fails. The error message provides details about the expected versus actual types. ```typescript expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() // error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: "Expected: string, Actual: number"; }' ``` -------------------------------- ### Type vs. Value Mode in expect-type Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/README.md Illustrates the difference between using generic type arguments (preferred for clearer errors) and inferring types from values. ```typescript // Generic type argument mode (preferred for clearer errors) expectTypeOf<{a: number}>().toEqualTypeOf<{a: number}>() // Inferred from value mode expectTypeOf({a: 1}).toEqualTypeOf({a: 1}) ``` -------------------------------- ### Type Definitions - Core Interfaces Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Key interfaces that form the foundation of the expect-type API. ```APIDOC ## Core Type Definitions ### Description These are the fundamental interfaces used within the expect-type library to define the structure of the assertion objects. ### Interfaces - **PositiveExpectTypeOf**: The main interface returned by `expectTypeOf`, providing all positive assertion methods. - **NegativeExpectTypeOf**: The interface used after `.not`, providing negated assertion methods. - **BaseExpectTypeOf**: An internal base interface. - **ExpectTypeOf**: An alias, often used interchangeably with `PositiveExpectTypeOf`. - **Branded**: A utility type for creating branded types. ### Usage Context These interfaces are primarily used internally by the library but understanding them helps in comprehending how the assertions are structured. ``` -------------------------------- ### Comparing Optional vs. Undefined Union Types Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/limitations-and-workarounds.md Illustrates that optional properties (`a?: T`) and properties explicitly typed as `T | undefined` are not equal but can extend each other. This example uses expect-type to verify the distinction. ```typescript type Optional = {a?: string} type WithUndefined = {a: string | undefined} // These are NOT equal: // expectTypeOf().not.toEqualTypeOf() // ✓ Passes - they're different // But they extend each other: // expectTypeOf().toExtend() // expectTypeOf().toExtend() ``` -------------------------------- ### Extract Overload Signatures with OverloadsInfoUnion Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Automatically selects the appropriate overload extraction method based on the TypeScript version. Use this to get a union of all overload signatures for a given function type. ```typescript export type OverloadsInfoUnion = IsNever 2>> extends true ? TSPre53OverloadsInfoUnion : TSPost53OverloadsInfoUnion ``` ```typescript type Divide = { (a: number, b: number): number (a: string, b: string): string } type AllOverloads = OverloadsInfoUnion // Result: ((a: number, b: number) => number) | ((a: string, b: string) => string) ``` -------------------------------- ### Get Useful Keys for Type Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/types.md Extracts 'useful' keys from a type. For arrays, it returns numeric indices; for objects, it returns all keys. Useful for creating mapped types based on key types. ```typescript export type UsefulKeys = T extends any[] ? {[K in keyof T]: K}[number] : keyof T ``` -------------------------------- ### Limitations & Workarounds - TypeScript Version Specific Issues Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Highlights issues related to specific TypeScript versions and potential bugs. ```APIDOC ## Limitation: TypeScript Version-Specific Issues ### Description Certain features or behaviors of `expect-type` might be affected by bugs or changes in specific TypeScript compiler versions. ### Limitation Details - Older TypeScript versions might have limitations in type inference or manipulation that `expect-type` relies on. - New features in newer TypeScript versions might not be immediately supported or could introduce new edge cases. - Specific bugs (e.g., pre-5.3 bugs mentioned) can cause assertions to pass or fail incorrectly. ### Workaround - **Update TypeScript**: Ensure you are using a recent and stable version of the TypeScript compiler. - **Check Compatibility**: Consult the `expect-type` documentation or repository for known compatibility issues with specific TypeScript versions. - **Isolate Issues**: If you suspect a version-specific bug, try reproducing the assertion in different TypeScript versions to confirm. ### Example (Conceptual) ```typescript // No direct code example, as this relates to the compiler environment. // If a bug is known in TS 5.2 regarding mapped types, and your assertion uses mapped types: // You might see unexpected failures in TS 5.2 that work in TS 5.3+. ``` ``` -------------------------------- ### Extract Union of Return Types from Function Overloads Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/function-overload-utilities.md Use `OverloadReturnTypes` to get a union of all possible return types from a function with multiple overloads. This is useful when the built-in `ReturnType` only captures the last overload. ```typescript export type OverloadReturnTypes = OverloadsInfoUnion extends InferFunctionType ? ReturnType : never ``` -------------------------------- ### Testing Instance Type Properties Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/usage-patterns.md Verify that instances of a class have specific properties, like methods. Useful for checking the public API of class instances. ```typescript class Observable { subscribe(listener: (value: T) => void): void {} } expectTypeOf(Observable) .instance.toHaveProperty('subscribe') expectTypeOf(Observable) .instance.toHaveProperty('subscribe') ``` -------------------------------- ### Debugging Type Information with .inspect Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/usage-patterns.md Use the .branded.inspect() method to get detailed type information for debugging, especially for complex types. The compiler will list any 'any' or 'never' types found within the inspected type. ```typescript // Use hover/IDE to inspect types const x = {} as typeof complexType expectTypeOf(x).branded.inspect({foundProps: {}}) // Compiler will list all any/never types found ``` -------------------------------- ### Limitations & Workarounds - .map() with Null/Undefined Complexity Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Discusses complexities when using `.map()` with `null` or `undefined`. ```APIDOC ## Limitation: `.map()` with Null/Undefined Complexity ### Description Using the `.map()` assertion method on types that involve `null` or `undefined` can sometimes lead to unexpected results due to TypeScript's type resolution rules. ### Limitation Details - Mapped types can behave differently when the base type includes `null` or `undefined`. - The transformation logic within `.map()` might not always handle these primitive types as intuitively as expected. ### Workaround - **Explicitly handle null/undefined**: If possible, use `extract` or `exclude` before mapping, or ensure your mapping function explicitly accounts for `null` and `undefined`. - **Test intermediate types**: Break down the mapping process and assert intermediate types to pinpoint where the issue occurs. ### Example (Conceptual) ```typescript import { expectTypeOf } from 'expect-type'; type NullableValue = { value: string | null }; // Example: Mapping to make the value non-nullable (conceptual) // This assumes a mapping function that handles null/undefined. // expectTypeOf().map<...>().toEqualTypeOf<{ value: string }>(); // A more direct approach might be needed if mapping is complex: expectTypeOf().value.toEqualTypeOf(); ``` ``` -------------------------------- ### Checking a Specific Property for 'any' Type Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/branding-and-deep-inspection.md Use .toBeAny() when you know the exact path to a property that should be of type 'any'. This is a targeted check for known locations. ```typescript type Data = { name: string meta: { parsed: JSON.parse(metadata) // any! } } // Use .toBeAny() when you already know where: expectTypeOf() .toHaveProperty('meta') .toHaveProperty('parsed') .toBeAny() ``` -------------------------------- ### Handling Overloaded Functions with .parameters and .returns Source: https://github.com/mmkal/expect-type/blob/main/README.md Demonstrates how expect-type handles union types for parameters and return values when dealing with overloaded functions. ```typescript type Factorize = { (input: number): number[] (input: bigint): bigint[] } expectTypeOf().parameters.not.toEqualTypeOf<[number]>() expectTypeOf().parameters.toEqualTypeOf<[number] | [bigint]>() expectTypeOf().returns.toEqualTypeOf() expectTypeOf().parameter(0).toEqualTypeOf() ``` -------------------------------- ### parameters Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/api-reference-assertions.md Extracts all function parameters as a tuple for assertions, supporting overloads. ```APIDOC ## parameters ### Description Extracts all function parameters as a tuple for assertions. ### Method `parameters` ### Request Example ```typescript function noParam() {} function hasParam(s: string) {} expectTypeOf(noParam).parameters.toEqualTypeOf<[]>() expectTypeOf(hasParam).parameters.toEqualTypeOf<[string]>() type Factorize = { (input: number): number[] (input: bigint): bigint[] } expectTypeOf().parameters.toEqualTypeOf<[number] | [bigint]>() ``` ### Response Returns an assertion interface for the tuple of function parameters. ``` -------------------------------- ### Usage Patterns - Error Handling and Debugging Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/FILE-MANIFEST.txt Strategies for handling errors and debugging type assertions. ```APIDOC ## Usage Pattern: Error Handling and Debugging ### Description Provides guidance on understanding and debugging type assertion failures. ### Strategies - **Read Assertion Messages**: TypeScript compiler errors for `expect-type` are usually descriptive. Pay close attention to the expected vs. received types. - **Use `.not`**: When an assertion fails unexpectedly, try negating it with `.not` to see if the types are fundamentally different than expected. - **Simplify Types**: Break down complex types into smaller, named types to isolate the issue. - **Check Overloads**: If dealing with functions, ensure you are testing the correct overload or the union of all overloads. - **Consult Limitations**: Refer to the 'Limitations & Workarounds' section for known issues with specific TypeScript features (e.g., deep types, complex generics). ### Example of Debugging Failure ```typescript import { expectTypeOf } from 'expect-type'; type Actual = { id: number; name: string }; type Expected = { id: number; name: string; age: number }; // This will fail with a TypeScript error: // expectTypeOf().toEqualTypeOf(); // Error message will indicate that 'Actual' is missing the 'age' property. // To fix, either adjust Actual or Expected, or use .pick/.omit if appropriate. ``` ``` -------------------------------- ### constructorParameters Source: https://github.com/mmkal/expect-type/blob/main/_autodocs/api-reference-assertions.md Extracts constructor parameters, supporting overloads, as a union tuple array for assertions. ```APIDOC ## constructorParameters ### Description Extracts constructor parameters (supports overloads) as a union tuple array. ### Method `constructorParameters` ### Request Example ```typescript expectTypeOf(Date).constructorParameters.toEqualTypeOf<[] | [string | number | Date]>() ``` ### Response Returns an assertion interface for the constructor parameters. ```