Ts Infer
`infer` is a keyword in TypeScript conditional types, used to infer a new type from an existing type.\\n\\nIt allows extracting and deducing types within generic conditional types, enabling powerful type manipulations.\\n\\n* * *\\n\\n* * *\\n\\n## Why the infer Keyword is Needed\\n\\nIn generic programming, we often need to extract partial types from complex types.\\n\\nFor example, extracting `string` from `Promise`, or extracting `User` from `Array`.\\n\\nThe `infer` keyword makes this type extraction elegant and type-safe. It can declare a type variable within a conditional type, which can then be used in the true branch.\\n\\n> **Concept Explanation:** `infer` is an abbreviation for "infer", meaning "to deduce". It can only be used in the `extends` clause of a conditional type to declare a type variable to be inferred.\\n\\n* * *\\n\\n## Basic Usage\\n\\nUse `infer` to infer types within conditional types.\\n\\n## Instance\\n\\n// From Promise Extract value type from\\n\\n// If T is PromiseοΌthen returns V; otherwise returns never\\n\\n type ValueOf= T extends Promise? V : never;\\n\\n// Test\\n\\n type Str = ValueOf>;// string\\n\\n type Num = ValueOf>;// number\\n\\n type NotPrm = ValueOf;// never\\n\\n// Usage example\\n\\nvar promise: Promise= Promise.resolve("hello");\\n\\nvar value: ValueOf="world";\\n\\nconsole.log("String extraction: "+(typeof value ==="string"?"Success":"Failure"));\\n\\n**Running Result:**\\n\\nString extraction: Success\\n> **Explanation:** `infer V` declares a type variable V, and TypeScript will automatically infer the type of V.\\n\\n* * *\\n\\n## Extracting Array Element Types\\n\\nExtract the element type from an array type.\\n\\n## Instance\\n\\n// Extract the element type of arrays\\n\\n// If T is array V[]οΌthen returns V\\n\\n type ArrayElement= T extends(infer V)[]? V : never;\\n\\n// Test\\n\\n type User ={ name: string };\\n\\n type Users = User[];\\n\\ntype E1 = ArrayElement;// string\\n\\n type E2 = ArrayElement;// User\\n\\n type E3 = ArrayElement;// neverοΌNon-array)\\n\\n// Usage example\\n\\nvar users: Users =[{ name:"Alice"}];\\n\\nvar element: ArrayElement= users;\\n\\nconsole.log("Element type: "+ element.name);\\n\\n> **Application:** This pattern is commonly used to extract specific types of elements from union types.\\n\\n* * *\\n\\n## Extracting Function Return Types\\n\\nExtract the return type from a function type.\\n\\n## Instance\\n\\n// Extract function return type\\n\\n type ReturnType= T extends(...args: any[])=> infer R ? R : any;\\n\\n// Test\\n\\nfunction getData(){\\n\\nreturn{ id:1, name:"Alice"};\\n\\n}\\n\\nfunction fetchUser(id: number): Promise{\\n\\nreturn Promise.resolve({ id, name:"Bob"});\\n\\n}\\n\\ntype R1 = ReturnType;// { id: number; name: string }\\n\\n type R2 = ReturnType;// Promise\\n\\n// Usage example\\n\\nvar result: R1 ={ id:1, name:"Test"};\\n\\n console.log("Return type: "+ JSON.stringify(result));\\n\\n> **Built-in Type:** TypeScript's built-in `ReturnType` utility type is implemented using `infer`.\\n\\n* * *\\n\\n## Extracting Function Parameter Types\\n\\nExtract the parameter types from a function type.\\n\\n< h2 class="example">Instance\\n\\n// Extract first parameter type of function\\n\\n type FirstParameter= T extends(first: infer P, ...rest: any[])=> any ? P : never;\\n\\n// Test\\n\\nfunction createUser(name: string, age: number): User {\\n\\nreturn{ id:1, name };\\n\\n}\\n\\nfunction logMessage(msg: string):void{\\n\\n console.log(msg);\\n\\n}\\n\\ntype P1 = FirstParameter;// string\\n\\n type P2 = FirstParameter;// string\\n\\n type P3 = FirstParameter<()=> void>;// never\\n\\n// Usage example\\n\\nvar nameParam: P1 ="Alice";\\n\\n console.log("Parameter type: "+ nameParam);\\n\\n> **Note:** You can use `...rest: any[]` to match any number of remaining parameters.\\n\\n* * *\\n\\n## Multiple infer\\n\\nUse multiple `infer` declarations within a single conditional type.\\n\\n## Instance\\n\\n// Extract the first two element types of tuples\\n\\n type FirstTwo= T extends[infer A, infer B, ...rest: any[]]?[A, B]: never;\\n\\n// Test\\n\\n type Tuple =[string, number,boolean];\\n\\n type FirstTwoTypes = FirstTwo;// [string, number]\\n\\n// Extract object properties\\n\\n type ObjectValue= T extends{ value: infer V }? V : never;\\n\\ntype WithValue ={ value: string; name: string };\\n\\n type ExtractedValue = ObjectValue;// string\\n\\n// Usage example\\n\\nvar tupleResult: FirstTwoTypes =["hello",123];\\n\\n console.log("Tuples: "+ JSON.stringify(tupleResult));\\n\\n> **Tuples:** Using `...rest: any[]` can match the remaining elements of a tuple.\\n\\n* * *\\n\\n## Using infer in Recursive Types\\n\\nUse `infer` in recursive type utilities to implement complex type manipulations.\\n\\n## Instance\\n\\n// Deep readonlyType - Recursively apply infer\\n\\n type DeepReadonly= T extends Function\\n\\n? T\\n\\n: T extends object\\n\\n?{ readonly : DeepReadonly}\\n\\n: T;\\n\\n// Test\\n\\ninterface User {\\n\\n name: string;\\n\\n address:{\\n\\n city: string;\\n\\n zip: string;\\n\\n};\\n\\n}\\n\\ntype ReadonlyUser = DeepReadonly;\\n\\n// Flatten Promise type\\n\\n type FlattenPromise= T extends Promise\\n\\n? U extends Promise\\n\\n? FlattenPromise\\n\\n: U\\n\\n: T;\\n\\ntype Nested = Promise>;\\n\\n type Flat = FlattenPromise;// string\\n\\n// Usage example\\n\\nvar user: ReadonlyUser ={\\n\\n name:"Alice",\\n\\n address:{ city:"Beijing", zip:"100000"}\\n\\n};\\n\\n// user.name = "Bob"; // Error: readonly\\n\\n console.log("Deep readonly: "+ user.name);\\n\\n> **Recursive infer:** Using `infer` in recursive types can achieve deep type transformations, such as deep readonly, deep partial, etc.\\n\\n* * *\\n\\n## Precautions\\n\\n* **Can only be used on the right side of extends:** `infer` can only be used in the `extends` clause of a conditional type\\n* **Declaring type variables:** Use `infer V` to declare a type variable to be inferred\\n* **Multiple uses allowed:** Multiple `infer` declarations can be used in a single conditional type\\n* **Returns never on inference failure:** If inference fails, the conditional type returns `never`\\n\\n> **Best Practice:** `infer` is the core of implementing custom utility types; mastering it enables powerful type manipulations.\\n\\n* * *\\n\\n## Summary\\n\\n`infer` is one of the most powerful features in the TypeScript type system.\\n\\n* **Type extraction:** Extract partial types from complex types\\n* **Conditional inference:** Infer types within conditional types\\n* **Function-related:** Extract function parameters and return types\\n* **Recursive utilities:** Implement deep type transformations\\n\\n> **Suggestion:** A deep understanding of `infer` allows you to write more advanced type utilities, improving type safety and development efficiency.
YouTip