All skills
Skillintermediate

Advanced Types

```typescript // Basic constraint function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; }

Claude Code Knowledge Pack7/10/2026

Overview

Advanced Types

Generic Constraints

// Basic constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// Multiple constraints
interface HasId { id: number; }
interface HasName { name: string; }

function merge(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

// Generic constraint with default
type ApiResponse =
  | { success: true; data: T }
  | { success: false; error: E };

// Constraint with infer
type UnwrapPromise = T extends Promise<infer U> ? U : T;
type Result = UnwrapPromise<Promise<string>>; // string

Conditional Types

// Basic conditional type
type IsString = T extends string ? true : false;

// Distributive conditional types
type ToArray = T extends any ? T[] : never;
type StringOrNumberArray = ToArray<string | number>; // string[] | number[]

// Non-distributive (use tuple)
type ToArrayNonDist = [T] extends [any] ? T[] : never;
type BothArray = ToArrayNonDist<string | number>; // (string | number)[]

// Nested conditionals for type extraction
type Flatten = T extends Array<infer U>
  ? U extends Array<infer V>
    ? Flatten
    : U
  : T;

type Nested = Flatten<string[][][]>; // string

// Exclude null/undefined
type NonNullable = T extends null | undefined ? never : T;

Mapped Types

// Basic mapped type
type ReadOnly = {
  readonly [K in keyof T]: T[K];
};

// Optional properties
type Partial = {
  [K in keyof T]?: T[K];
};

// Required properties
type Required = {
  [K in keyof T]-?: T[K]; // Remove optional modifier
};

// Key remapping with 'as'
type Getters = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface Person {
  name: string;
  age: number;
}

type PersonGetters = Getters;
// { getName: () => string; getAge: () => number; }

// Filtering keys
type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

type StringFields = PickByType<Person, string>; // { name: string }

Template Literal Types

// Basic template literal
type EmailLocale = 'en' | 'es' | 'fr';
type EmailType = 'welcome' | 'reset-password';
type EmailTemplate = `${EmailLocale}_${EmailType}`;
// 'en_welcome' | 'en_reset-password' | 'es_welcome' | ...

// Intrinsic string manipulation
type Uppercase = intrinsic;
type Lowercase = intrinsic;
type Capitalize = intrinsic;
type Uncapitalize = intrinsic;

type EventName = `on${Capitalize}`;
type ClickEvent = EventName<'click'>; // 'onClick'

// Template literal with mapped types
type CSSProperties = {
  [K in 'color' | 'background' | 'border' as `--${K}`]: string;
};
// { '--color': string; '--background': string; '--border': string }

// Pattern matching with infer
type ExtractRouteParams =
  T extends `${infer _Start}/:${infer Param}/${infer Rest}`
    ? Param | ExtractRouteParams<`/${Rest}`>
    : T extends `${infer _Start}/:${infer Param}`
    ? Param
    : never;

type Params = ExtractRouteParams<'/users/:id/posts/:postId'>; // 'id' | 'postId'

Higher-Kinded Types (Simulation)

// Type-level function simulation
interface TypeClass {
  map: <A, B>(f: (a: A) => B, fa: any) => any;
}

// Functor pattern
type Maybe = { type: 'just'; value: T } | { type: 'nothing' };

const MaybeFunctor: TypeClass<Maybe<any>> = {
  map: <A, B>(f: (a: A) => B, ma: Maybe): Maybe => {
    return ma.type === 'just'
      ? { type: 'just', value: f(ma.value) }
      : { type: 'nothing' };
  }
};

// Builder pattern with generics
type Builder<T, K extends keyof T = never> = {
  with>(
    key: P,
    value: T[P]
  ): Builder<T, K | P>;
  build(): K extends keyof T ? T : never;
};

Recursive Types

// JSON type
type JSONValue =
  | string
  | number
  | boolean
  | null
  | JSONValue[]
  | { [key: string]: JSONValue };

// Deep partial
type DeepPartial = T extends object ? {
  [K in keyof T]?: DeepPartial<T[K]>;
} : T;

// Deep readonly
type DeepReadonly = T extends object ? {
  readonly [K in keyof T]: DeepReadonly<T[K]>;
} : T;

// Path type for nested objects
type PathsToProps = T extends object ? {
  [K in keyof T]: K extends string
    ? T[K] extends object
      ? K | `${K}.${PathsToProps<T[K]>}`
      : K
    : never;
}[keyof T] : never;

interface User {
  profile: {
    name: string;
    settings: {
      theme: string;
    };
  };
}

type UserPaths = PathsToProps;
// 'profile' | 'profile.name' | 'profile.settings' | 'profile.settings.theme'

Variance and Contravariance

// Covariance (return types)
type Producer = () => T;
let stringProducer: Producer<string> = () => 'hello';
let objectProducer: Producer<object> = stringProducer; // OK: string is object

// Contravariance (parameter types)
type Consumer = (value: T) => void;
let objectConsumer: Consumer<object> = (obj) => console.log(obj);
let stringConsumer: Consumer<string> = objectConsumer; // OK in strict mode

// Invariance (mutable properties)
interface Box {
  value: T;
  setValue(v: T): void;
}

let stringBox: Box<string> = { value: '', setValue: (v) => {} };
// let objectBox: Box<object> = stringBox; // Error: invariant

Type-Level Programming

// Type-level addition (limited)
type Length = T['length'];
type Concat = [...A, ...B];

// Type-level conditionals
type If =
  Condition extends true ? Then : Else;

// Type-level equality
type Equal<X, Y> =
  (() => T extends X ? 1 : 2) extends
  (() => T extends Y ? 1 : 2) ? true : false;

// Assert equal types (for testing)
type Assert = T;
type Test = Assert<Equal<1 | 2, 2 | 1>>; // OK

Quick Reference

PatternUse Case
T extends U ? X : YConditional type logic
infer RExtract types from patterns
K in keyof TIterate over object keys
as NewKeyRemap keys in mapped types
Template literalsString pattern types
T extends anyDistributive conditionals
[T] extends [any]Non-distributive check
-? modifierRemove optional
readonly modifierMake immutable