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-index-signatures.mdreferences/

Index Signatures & Dynamic Properties

Basic Index Signatures

Allow dynamic property access with consistent types.

interface StringDictionary {
  [key: string]: string;
}

const dict: StringDictionary = {
  name: 'John',
  role: 'Developer'
};

console.log(dict['name']); // ✅ string
console.log(dict['anything']); // ✅ string (might be undefined at runtime!)

Numeric Index Signatures

interface NumberArray {
  [index: number]: string;
}

const arr: NumberArray = ['a', 'b', 'c'];
console.log(arr[0]); // ✅ string

Mixed with Known Properties

interface Config {
  name: string;
  version: number;
  [key: string]: string | number; // Known properties must match
}

const config: Config = {
  name: 'app',
  version: 1,
  author: 'John', // ✅ Additional properties allowed
  year: 2024
};

Rule: Known property types must be assignable to the index signature type.

Template Literal in Index Signatures (TypeScript 4.4+)

interface Getters {
  [K: `get${string}`]: () => any;
}

const obj: Getters = {
  getName: () => 'John',
  getAge: () => 30,
  // setName: () => {} // ❌ Error: must start with 'get'
};

Record Utility Type

// Shorthand for index signature
type StringMap = Record<string, string>;

// With specific keys
type Roles = Record<'admin' | 'user' | 'guest', string[]>;

const permissions: Roles = {
  admin: ['read', 'write', 'delete'],
  user: ['read', 'write'],
  guest: ['read']
};

Restricting Keys

// Only specific keys allowed
type AllowedKeys = 'name' | 'age' | 'email';
type UserData = Record<AllowedKeys, string>;

const user: UserData = {
  name: 'John',
  age: '30',
  email: 'john@example.com'
  // role: 'admin' // ❌ Error: role not in AllowedKeys
};

Combining with Mapped Types

type Optional<T> = {
  [K in keyof T]?: T[K];
};

type WithDefaults<T> = {
  [K in keyof T]: T[K] | null;
};

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

type PartialUser = Optional<User>;
// { name?: string; age?: number; }

type NullableUser = WithDefaults<User>;
// { name: string | null; age: number | null; }

noUncheckedIndexedAccess

Stricter type checking for index access:

// tsconfig.json
{
  "compilerOptions": {
    "noUncheckedIndexedAccess": true
  }
}

interface Dict {
  [key: string]: string;
}

const dict: Dict = { name: 'John' };
const value = dict['anything']; // Type: string | undefined (safer!)

Best Practices

  1. Use Record<K, V> for simple cases - More concise than index signatures
  2. Enable noUncheckedIndexedAccess - Catches potential undefined access
  3. Prefer known properties - Index signatures are for truly dynamic data
  4. Consider Map for dynamic data - Better runtime guarantees
  5. Document expected keys - Comment what keys are expected

Common Patterns

Environment Variables

interface ProcessEnv {
  NODE_ENV: 'development' | 'production' | 'test';
  [key: string]: string | undefined;
}

declare const process: {
  env: ProcessEnv;
};

API Response with Dynamic Fields

interface ApiResponse<T> {
  status: number;
  data: T;
  [key: string]: unknown; // Additional metadata
}

Configuration with Sections

interface AppConfig {
  [section: string]: {
    [key: string]: string | number | boolean;
  };
}

const config: AppConfig = {
  database: {
    host: 'localhost',
    port: 5432
  },
  cache: {
    enabled: true,
    ttl: 3600
  }
};

Common Pitfalls

  • Assuming indexed values exist - Always check for undefined
  • Too permissive types - Index signature any defeats type safety
  • Mixing incompatible known properties - Known properties must match index signature type
  • Using index signatures for fixed shapes - Use explicit properties instead

Install with Tessl CLI

npx tessl i pantheon-ai/typescript-advanced@0.1.1

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