Comprehensive guide to TypeScript generic types, constraints, defaults, and conditional types with practical examples
This skill helps you understand and implement TypeScript generics, including type constraints, defaults, conditional types, and advanced generic patterns.
Provides comprehensive guidance on TypeScript's generic type system, enabling you to:
When a user asks about TypeScript generics or needs help with generic type patterns, follow these steps:
Determine what the user needs:
**Basic Generics:**
**Example:**
```typescript
function identity<Type>(arg: Type): Type {
return arg;
}
// Usage with explicit type
let output1 = identity<string>("myString");
// Usage with type inference
let output2 = identity("myString"); // Type inferred as string
```
When generics need specific properties or methods:
```typescript
interface Lengthwise {
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
console.log(arg.length); // Now we know it has .length
return arg;
}
// Works with arrays, strings, or objects with length
loggingIdentity([1, 2, 3]);
loggingIdentity("hello");
loggingIdentity({ length: 10, value: 3 });
```
**Generic Interfaces:**
```typescript
interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
```
**Generic Classes:**
```typescript
class GenericNumber<NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;
```
**Using Type Parameters in Constraints:**
```typescript
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3 };
getProperty(x, "a"); // OK
getProperty(x, "m"); // Error: "m" is not in type
```
**Generic Constraints with Class Types:**
```typescript
function create<Type>(c: { new (): Type }): Type {
return new c();
}
```
**Conditional Types:**
```typescript
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
```
**Array Operations:**
```typescript
function firstElement<Type>(arr: Type[]): Type | undefined {
return arr[0];
}
```
**Promise Wrappers:**
```typescript
async function fetchData<T>(url: string): Promise<T> {
const response = await fetch(url);
return response.json();
}
```
**Generic Defaults:**
```typescript
interface Dictionary<T = string> {
[key: string]: T;
}
let strDict: Dictionary = {}; // T defaults to string
let numDict: Dictionary<number> = {};
```
**Example 1: Generic API Response Handler**
```typescript
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
async function fetchApi<T>(endpoint: string): Promise<ApiResponse<T>> {
const response = await fetch(endpoint);
return response.json();
}
// Usage
interface User {
id: number;
name: string;
}
const userResponse = await fetchApi<User>("/api/user");
console.log(userResponse.data.name); // Type-safe!
```
**Example 2: Generic Repository Pattern**
```typescript
interface Entity {
id: string | number;
}
class Repository<T extends Entity> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
findById(id: T['id']): T | undefined {
return this.items.find(item => item.id === id);
}
getAll(): T[] {
return [...this.items];
}
}
interface Product extends Entity {
id: number;
name: string;
price: number;
}
const productRepo = new Repository<Product>();
productRepo.add({ id: 1, name: "Widget", price: 9.99 });
```
Based on the official TypeScript Handbook: https://www.typescriptlang.org/docs/handbook/2/generics.html
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/typescript-generics-guide/raw