CtrlK
BlogDocsLog inGet started
Tessl Logo

pantheon-ai/typescript-advanced

Comprehensive TypeScript guidance covering compiler configuration, advanced types, utility types, type guards, strict mode workflows, and documentation patterns; use when configuring tsconfig, designing complex generics, making illegal states unrepresentable, fixing type errors, or writing testable and maintainable type-safe APIs.

Overall
score

99%

Does it follow best practices?

Validation for skill structure

Overview
Skills
Evals
Files

types-mapped.mdreferences/

Mapped Types

Basic Mapped Types

Transform properties of existing types:

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

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

type Required<T> = {
  [P in keyof T]-?: T[P]; // Remove optional modifier
};

interface User {
  name: string;
  age?: number;
}

type ReadonlyUser = Readonly<User>;
// { readonly name: string; readonly age?: number }

type CompleteUser = Required<User>;
// { name: string; age: number }

Key Remapping

Transform property keys with as:

type Getters<T> = {
  [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
};

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

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

Filtering Properties

Use conditional types with never to filter:

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

interface Mixed {
  name: string;
  age: number;
  active: boolean;
  score: number;
}

type StringProps = PickByType<Mixed, string>;
// { name: string }

type NumberProps = PickByType<Mixed, number>;
// { age: number; score: number }

Modifiers

Add or remove modifiers:

// Remove readonly
type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

// Remove optional
type Concrete<T> = {
  [P in keyof T]-?: T[P];
};

// Add both
type Frozen<T> = {
  readonly [P in keyof T]-?: T[P];
};

Nested Mapped Types

Recursively transform nested objects:

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object
    ? DeepPartial<T[P]>
    : T[P];
};

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

interface Config {
  database: {
    host: string;
    port: number;
    credentials: {
      username: string;
      password: string;
    };
  };
}

type PartialConfig = DeepPartial<Config>;
// All properties at all levels are optional

Template Literal Key Remapping

Combine with template literal types:

type EventHandlers<T> = {
  [P in keyof T as `on${Capitalize<string & P>}Change`]: (
    value: T[P]
  ) => void;
};

interface Form {
  username: string;
  email: string;
  age: number;
}

type FormHandlers = EventHandlers<Form>;
// {
//   onUsernameChange: (value: string) => void;
//   onEmailChange: (value: string) => void;
//   onAgeChange: (value: number) => void;
// }

Conditional Mapped Types

type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

type NullableStrings<T> = {
  [P in keyof T]: T[P] extends string ? T[P] | null : T[P];
};

interface Data {
  name: string;
  age: number;
  email: string;
}

type Result = NullableStrings<Data>;
// {
//   name: string | null;
//   age: number;
//   email: string | null;
// }

Advanced Patterns

Proxied Properties

type Proxied<T> = {
  [P in keyof T]: {
    get(): T[P];
    set(value: T[P]): void;
  };
};

Prefixed Properties

type Prefix<T, P extends string> = {
  [K in keyof T as `${P}${Capitalize<string & K>}`]: T[K];
};

type User = { name: string; age: number };
type OldUser = Prefix<User, 'old'>;
// { oldName: string; oldAge: number }

Omit by Type

type OmitByType<T, U> = {
  [P in keyof T as T[P] extends U ? never : P]: T[P];
};

interface Mixed {
  name: string;
  age: number;
  active: boolean;
}

type NoStrings = OmitByType<Mixed, string>;
// { age: number; active: boolean }

Readonly Keys

type ReadonlyKeys<T> = {
  [P in keyof T]-?: (<F>() => F extends { [Q in P]: T[P] } ? 1 : 2) extends
    (<F>() => F extends { -readonly [Q in P]: T[P] } ? 1 : 2)
    ? never
    : P;
}[keyof T];

Required Keys

type RequiredKeys<T> = {
  [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
}[keyof T];

type OptionalKeys<T> = {
  [K in keyof T]-?: {} extends Pick<T, K> ? K : never;
}[keyof T];

Practical Examples

Form State

type FormState<T> = {
  [P in keyof T]: {
    value: T[P];
    error?: string;
    touched: boolean;
  };
};

Async Versions

type Promisify<T> = {
  [P in keyof T]: T[P] extends (...args: infer A) => infer R
    ? (...args: A) => Promise<R>
    : T[P];
};

Builder Pattern

type Builder<T> = {
  [P in keyof T as `set${Capitalize<string & P>}`]: (value: T[P]) => Builder<T>;
} & {
  build(): T;
};

Best Practices

  1. Use built-in mapped types (Partial, Readonly, Pick, Omit) when possible
  2. Leverage key remapping for type-safe transformations
  3. Combine with conditional types for filtering
  4. Use template literals for systematic renaming
  5. Be careful with recursive mapped types (performance)

Common Pitfalls

  1. Don't map over union types - use distributive conditional types instead
  2. Avoid overly complex key remapping logic
  3. Be careful with recursive depth limits
  4. Don't forget about modifier removal (-readonly, -?)
  5. Watch out for preserving optional modifiers

Performance Considerations

  • Mapped types can be expensive for large types
  • Recursive mapped types multiply compilation time
  • Consider caching results for frequently-used transformations
  • Keep nesting depth reasonable

Install with Tessl CLI

npx tessl i pantheon-ai/typescript-advanced

references

compiler-module-resolution.md

compiler-performance.md

compiler-strict-mode.md

compiler-tsconfig.md

docs-adr-templates.md

docs-framework-docs.md

docs-jsdoc-patterns.md

docs-typedoc-config.md

guards-assertion-functions.md

guards-basic.md

guards-branded-types.md

guards-discriminated-unions.md

guards-exhaustiveness.md

guards-generic.md

guards-inference-infer.md

guards-inference-return.md

patterns-advanced-generics.md

patterns-api-client.md

patterns-branded-types.md

patterns-builder.md

patterns-deep-readonly.md

patterns-dependency-injection.md

patterns-event-emitter.md

patterns-form-validation.md

patterns-plugin-system.md

patterns-recursive-types.md

patterns-state-machine.md

patterns-type-safe-module.md

practices-illegal-states.md

practices-module-patterns.md

practices-runtime-validation.md

practices-type-first.md

types-conditional.md

types-generics.md

types-index-signatures.md

types-mapped.md

types-narrowing.md

types-template-literals.md

types-type-assertions.md

types-unions-intersections.md

utilities-custom-mapped-types.md

utilities-extract-exclude.md

utilities-key-remapping.md

utilities-nonnullable-awaited.md

utilities-partial-required.md

utilities-pick-omit.md

utilities-readonly-record.md

utilities-returntype-parameters.md

SKILL.md

tile.json