typescript-advanced-types

Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.

210 stars

Best use case

typescript-advanced-types is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.

Teams using typescript-advanced-types should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/typescript-advanced-types/SKILL.md --create-dirs "https://raw.githubusercontent.com/flpbalada/my-opencode-config/main/skills/typescript-advanced-types/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/typescript-advanced-types/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How typescript-advanced-types Compares

Feature / Agenttypescript-advanced-typesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# TypeScript Advanced Types

Comprehensive guidance for mastering TypeScript's advanced type system including generics, conditional types, mapped types, template literal types, and utility types for building robust, type-safe applications.

## When to Use This Skill

- Building type-safe libraries or frameworks
- Creating reusable generic components
- Implementing complex type inference logic
- Designing type-safe API clients
- Building form validation systems
- Creating strongly-typed configuration objects
- Implementing type-safe state management
- Migrating JavaScript codebases to TypeScript

## Core Concepts

### 1. Generics

Create reusable, type-flexible components while maintaining type safety.

```typescript
function identity<T>(value: T): T {
  return value;
}

const num = identity<number>(42);        // Type: number
const str = identity<string>("hello");   // Type: string
const auto = identity(true);              // Type inferred: boolean
```

### 2. Conditional Types

Create types that depend on conditions.

```typescript
type IsString<T> = T extends string ? true : false;

type A = IsString<string>;    // true
type B = IsString<number>;    // false
```

### 3. Mapped Types

Transform existing types by iterating over their properties.

```typescript
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Partial<T> = {
  [P in keyof T]?: T[P];
};
```

### 4. Template Literal Types

Create string-based types with pattern matching.

```typescript
type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// Type: "onClick" | "onFocus" | "onBlur"
```

### 5. Utility Types

Built-in utility types for common transformations:

```typescript
Partial<T>      // Make all properties optional
Required<T>     // Make all properties required
Readonly<T>     // Make all properties readonly
Pick<T, K>      // Select specific properties
Omit<T, K>      // Remove specific properties
```

## The Golden Rule of Generics

**If a type parameter appears only in the function signature, it's likely unnecessary.**

```typescript
// Bad - T only appears in signature, not in return or body
function getRelationName<T extends 'department' | 'location'>(
  data: Career['data'],
  field: T
): string | null {
  return data?.[field]?.name ?? null
}

// Good - no unnecessary generic, use union directly
function getRelationName(
  data: Career['data'],
  field: 'department' | 'location' | 'employmentType'
): string | null {
  return data?.[field]?.name ?? null
}
```

## Progressive Disclosure

This skill provides detailed examples through context files. Load them when needed:

| Context File                      | When to Load                                    |
| --------------------------------- | ----------------------------------------------- |
| `context/core-examples.md`       | Need generics, conditionals, mapped types examples |
| `context/patterns.md`            | Implementing real-world patterns (EventEmitter, API client, Builder) |
| `context/techniques.md`          | Type inference, guards, assertions, testing     |

## Type Inference Techniques

### Infer Keyword

```typescript
type ElementType<T> = T extends (infer U)[] ? U : never;
type PromiseType<T> = T extends Promise<infer U> ? U : never;
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
```

### Type Guards

```typescript
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function isArrayOf<T>(
  value: unknown,
  guard: (item: unknown) => item is T
): value is T[] {
  return Array.isArray(value) && value.every(guard);
}
```

### Assertion Functions

```typescript
function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== "string") {
    throw new Error("Not a string");
  }
}
```

## StrictOmit for Safer Property Exclusion

```typescript
// Problem: Omit doesn't validate key exists
type UserWithoutPassword = Omit<User, 'passwrod'>; // No error for typo

// Solution: StrictOmit validates the key exists
type StrictOmit<T, K extends keyof T> = Omit<T, K>;
type SafeUser = StrictOmit<User, 'passwrod'>; // TypeScript error!
```

## Branded Types for Nominal Typing

```typescript
type UniformResourceLocator = string & { _brand: 'url' };

const isURL = (candidate: unknown): candidate is UniformResourceLocator => {
  return z.url().safeParse(candidate).success;
};

function fetchFromAPI(url: UniformResourceLocator) { /* ... */ }

const url = 'https://example.com';
// fetchFromAPI(url); // Error! Not branded

if (isURL(url)) {
  fetchFromAPI(url); // OK - type guard validated
}
```

## Best Practices

1. **Use `unknown` over `any`**: Enforce type checking
2. **Prefer `interface` for object shapes**: Better error messages
3. **Use `type` for unions and complex types**: More flexible
4. **Leverage type inference**: Let TypeScript infer when possible
5. **Create helper types**: Build reusable type utilities
6. **Use const assertions**: Preserve literal types
7. **Avoid type assertions**: Use type guards instead
8. **Document complex types**: Add JSDoc comments
9. **Use strict mode**: Enable all strict compiler options
10. **Test your types**: Use type tests to verify type behavior

## Common Pitfalls

1. **Over-using `any`**: Defeats the purpose of TypeScript
2. **Ignoring strict null checks**: Can lead to runtime errors
3. **Too complex types**: Can slow down compilation
4. **Not using discriminated unions**: Misses type narrowing opportunities
5. **Forgetting readonly modifiers**: Allows unintended mutations
6. **Circular type references**: Can cause compiler errors
7. **Not handling edge cases**: Like empty arrays or null values
8. **Unused generic parameters**: Violate the Golden Rule

## Performance Considerations

- Avoid deeply nested conditional types
- Use simple types when possible
- Cache complex type computations
- Limit recursion depth in recursive types
- Use build tools to skip type checking in production

## Infer Types from Zod Schemas

```typescript
// Avoid duplication
const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
});

type User = z.infer<typeof userSchema>;
```

## References

- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/)
- [Type Challenges](https://github.com/type-challenges/type-challenges)
- [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/)
- [Effective TypeScript](https://effectivetypescript.com/2020/08/12/generics-golden-rule/)

Related Skills

typescript-satisfies-operator

210
from flpbalada/my-opencode-config

Guides proper usage of TypeScript's satisfies operator vs type annotations. Use this skill when deciding between type annotations (colon) and satisfies, validating object shapes while preserving literal types, or troubleshooting type inference issues.

typescript-interface-vs-type

210
from flpbalada/my-opencode-config

Guides when to use interface vs type in TypeScript. Use this skill when defining object types, extending types, or choosing between interface and type aliases.

typescript-best-practices

210
from flpbalada/my-opencode-config

Guides TypeScript best practices for type safety, code organization, and maintainability. Use this skill when configuring TypeScript projects, deciding on typing strategies, writing async code, or reviewing TypeScript code quality.

what-not-to-do-as-product-manager

210
from flpbalada/my-opencode-config

Anti-patterns and mistakes to avoid as a product manager. Use when evaluating leadership behaviors, improving team dynamics, reflecting on management practices, or onboarding new product managers.

visual-cues-cta-psychology

210
from flpbalada/my-opencode-config

Design effective CTAs using visual attention and gaze psychology principles. Use when designing landing pages, button hierarchies, conversion elements, or optimizing user attention flow through interfaces.

vercel-sandbox

210
from flpbalada/my-opencode-config

Run agent-browser + Chrome inside Vercel Sandbox microVMs for browser automation from any Vercel-deployed app. Use when the user needs browser automation in a Vercel app (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.), wants to run headless Chrome without binary size limits, needs persistent browser sessions across commands, or wants ephemeral isolated browser environments. Triggers include "Vercel Sandbox browser", "microVM Chrome", "agent-browser in sandbox", "browser automation on Vercel", or any task requiring Chrome in a Vercel Sandbox.

value-realization

210
from flpbalada/my-opencode-config

Analyze if end users discover clear value. Use when evaluating product concepts, analyzing adoption, or uncertain about direction.

user-story-fundamentals

210
from flpbalada/my-opencode-config

Capture requirements from user perspective with structured user stories. Use when writing backlog items, defining acceptance criteria, prioritizing features, or communicating requirements between product and development.

trust-psychology

210
from flpbalada/my-opencode-config

Build trust signals that reduce perceived risk and enable user action. Use when designing landing pages, checkout flows, onboarding experiences, or any conversion point where user hesitation is a barrier.

theme-epic-story

210
from flpbalada/my-opencode-config

Structure product work hierarchically using themes, epics, and stories. Use when organizing backlogs, planning releases, communicating with stakeholders, or breaking down large initiatives into manageable work.

tailwind-v4-configuration

210
from flpbalada/my-opencode-config

Configure Tailwind CSS v4 with CSS-first approach. Use when installing, migrating from v3, setting up build tools (Vite/PostCSS/CLI), customizing themes with @theme, or configuring plugins.

status-quo-bias

210
from flpbalada/my-opencode-config

Understand and design for users' preference for current state over change. Use when planning migrations, introducing new features, designing defaults, or overcoming resistance to product adoption.