Conditional types in TypeScript allow you to create types that depend on a condition. They are a powerful feature that can make your type definitions more flexible and expressive. This topic will cover the basics of conditional types, provide practical examples, and include exercises to help you understand and apply this concept.
Key Concepts
-
Basic Syntax: The basic syntax of a conditional type is
T extends U ? X : Y, where:Tis the type you are checking.Uis the type you are comparing against.Xis the type returned ifTextendsU.Yis the type returned ifTdoes not extendU.
-
Usage: Conditional types are often used to create more specific types based on certain conditions.
-
Distributive Conditional Types: When conditional types are applied to a union type, they are distributed over each member of the union.
Practical Examples
Example 1: Basic Conditional Type
type IsString<T> = T extends string ? "Yes" : "No"; // Usage type A = IsString<string>; // "Yes" type B = IsString<number>; // "No"
Explanation:
IsStringis a conditional type that checks ifTextendsstring.- If
Tis astring, it returns"Yes", otherwise it returns"No".
Example 2: Conditional Type with Union
type ToArray<T> = T extends any ? T[] : never; // Usage type A = ToArray<string>; // string[] type B = ToArray<number>; // number[] type C = ToArray<string | number>; // string[] | number[]
Explanation:
ToArrayis a conditional type that converts a typeTto an array ofT.- If
Tis a union type, the conditional type is distributed over each member of the union.
Example 3: Nested Conditional Types
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
// Usage
type A = TypeName<string>; // "string"
type B = TypeName<() => void>; // "function"
type C = TypeName<{}>; // "object"Explanation:
TypeNameis a nested conditional type that returns a string representation of the typeT.- It checks multiple conditions to determine the type of
T.
Exercises
Exercise 1: Create a conditional type IsArray<T> that checks if a type T is an array.
type IsArray<T> = T extends any[] ? "Array" : "Not Array"; // Test cases type Test1 = IsArray<string[]>; // "Array" type Test2 = IsArray<number>; // "Not Array" type Test3 = IsArray<[number, string]>; // "Array"
Exercise 2: Create a conditional type Flatten<T> that flattens an array type T.
type Flatten<T> = T extends (infer U)[] ? U : T; // Test cases type Test1 = Flatten<string[]>; // string type Test2 = Flatten<number[][]>; // number[] type Test3 = Flatten<number>; // number
Exercise 3: Create a conditional type ReturnType<T> that extracts the return type of a function type T.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never; // Test cases type Test1 = ReturnType<() => string>; // string type Test2 = ReturnType<(x: number) => boolean>; // boolean type Test3 = ReturnType<() => void>; // void
Common Mistakes and Tips
-
Mistake: Forgetting that conditional types distribute over union types.
- Tip: Always consider how your conditional type will behave with union types.
-
Mistake: Using conditional types without understanding the
extendskeyword.- Tip: Make sure you understand how
extendsworks in TypeScript before using conditional types.
- Tip: Make sure you understand how
-
Mistake: Overcomplicating type definitions with nested conditional types.
- Tip: Keep your type definitions as simple as possible and only use nested conditional types when necessary.
Conclusion
Conditional types are a powerful feature in TypeScript that allow you to create types based on conditions. They can make your type definitions more flexible and expressive. By understanding the basic syntax and usage of conditional types, you can leverage them to create more dynamic and adaptable types in your TypeScript code. Practice with the provided exercises to reinforce your understanding and apply conditional types effectively.
TypeScript Course
Module 1: Introduction to TypeScript
- What is TypeScript?
- Setting Up the TypeScript Environment
- Basic Types
- Type Annotations
- Compiling TypeScript
Module 2: Working with Types
Module 3: Advanced Types
Module 4: Functions and Modules
Module 5: Asynchronous Programming
Module 6: Tooling and Best Practices
- Linting and Formatting
- Testing TypeScript Code
- TypeScript with Webpack
- TypeScript with React
- Best Practices
