Skip to content
Back to skills

Strict Typescript

ASecurity

Enforce strict TypeScript compiler settings and type narrowing patterns. Use when the user creates a new TypeScript project, configures tsconfig.json, encounters null/undefined errors, deals with indexed access issues, or asks about strict mode, type safety, or narrowing techniques.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
data-aitypescriptrustgodebugging

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add VersoXBT/claude-initial-setup --skill strict-typescript --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Strict Typescript?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Strict Typescript
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/versoxbt-strict-typescript/badge)](https://www.skillsdirectory.com/skills/versoxbt-strict-typescript)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: strict-typescript
description: >
  Enforce strict TypeScript compiler settings and type narrowing patterns.
  Use when the user creates a new TypeScript project, configures tsconfig.json,
  encounters null/undefined errors, deals with indexed access issues, or asks
  about strict mode, type safety, or narrowing techniques.
---

# Strict TypeScript Configuration

Enforce the strictest TypeScript compiler settings and apply proper type narrowing
to eliminate runtime type errors at compile time.

## When to Use
- Setting up or reviewing tsconfig.json
- Encountering "possibly undefined" or "possibly null" errors
- Accessing objects by dynamic keys or array indices
- Configuring a new TypeScript project from scratch
- Debugging type-related runtime errors

## Core Patterns

### Pattern 1: Essential Strict Settings

Always enable the full strict family plus additional safety flags.

```jsonc
// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noPropertyAccessFromIndexSignature": true,
    "forceConsistentCasingInFileNames": true,
    "verbatimModuleSyntax": true
  }
}
```

`strict: true` enables: `strictNullChecks`, `strictFunctionTypes`, `strictBindCallApply`,
`strictPropertyInitialization`, `noImplicitAny`, `noImplicitThis`,
`useUnknownInCatchVariables`, `alwaysStrict`.

### Pattern 2: Safe Indexed Access with noUncheckedIndexedAccess

With `noUncheckedIndexedAccess`, every index signature access returns `T | undefined`.

```typescript
const scores: Record<string, number> = { alice: 95, bob: 87 };

// Without noUncheckedIndexedAccess: score is number (WRONG at runtime)
// With noUncheckedIndexedAccess: score is number | undefined (CORRECT)
const score = scores["charlie"];

// You must narrow before using
if (score !== undefined) {
  console.log(score.toFixed(2)); // safe
}

// Same applies to arrays
const items = ["a", "b", "c"];
const item = items[5]; // string | undefined -- forces you to check
```

### Pattern 3: Type Narrowing Techniques

Use narrowing to convert broad types into specific ones without unsafe casts.

```typescript
// typeof narrowing
function process(value: string | number): string {
  if (typeof value === "string") {
    return value.toUpperCase(); // narrowed to string
  }
  return value.toFixed(2); // narrowed to number
}

// in narrowing
interface Dog { bark(): void }
interface Cat { meow(): void }

function speak(animal: Dog | Cat): void {
  if ("bark" in animal) {
    animal.bark(); // narrowed to Dog
  } else {
    animal.meow(); // narrowed to Cat
  }
}

// instanceof narrowing
function formatError(err: unknown): string {
  if (err instanceof Error) {
    return err.message; // narrowed to Error
  }
  return String(err);
}
```

### Pattern 4: exactOptionalPropertyTypes

Distinguishes between "missing" and "explicitly undefined" properties.

```typescript
interface Config {
  debug?: boolean;
  // With exactOptionalPropertyTypes:
  // debug can be omitted OR set to true/false
  // but NOT set to undefined explicitly
}

// Valid
const a: Config = {};
const b: Config = { debug: true };

// Invalid with exactOptionalPropertyTypes
// const c: Config = { debug: undefined }; // Error!

// Use union with undefined if you need explicit undefined
interface FlexibleConfig {
  debug?: boolean | undefined; // now explicit undefined is allowed
}
```

### Pattern 5: Assertion Functions and Type Predicates

Create reusable narrowing with custom type guards.

```typescript
// Type predicate
function isNonNull<T>(value: T | null | undefined): value is T {
  return value != null;
}

const values = [1, null, 2, undefined, 3];
const clean: number[] = values.filter(isNonNull); // number[]

// Assertion function
function assertDefined<T>(
  value: T | null | undefined,
  name: string
): asserts value is T {
  if (value == null) {
    throw new Error(`Expected ${name} to be defined`);
  }
}

function processUser(id: string | undefined): void {
  assertDefined(id, "id");
  // id is now string -- no need for further checks
  console.log(id.toUpperCase());
}
```

## Anti-Patterns

- **Using `as` to silence errors** -- Type assertions bypass the compiler. Use narrowing instead.
  ```typescript
  // BAD: hiding the problem
  const name = (data as any).user.name;
  // GOOD: validate the shape
  if (data && typeof data === "object" && "user" in data) { ... }
  ```

- **Using the non-null assertion `!`** -- Tells the compiler to trust you, but you might be wrong.
  ```typescript
  // BAD
  const el = document.getElementById("app")!;
  // GOOD
  const el = document.getElementById("app");
  if (!el) throw new Error("Missing #app element");
  ```

- **Disabling strict flags per file with `// @ts-ignore`** -- Fix the types instead of ignoring them.

- **Using `any` instead of `unknown`** -- Prefer `unknown` and narrow. `any` disables type checking entirely.

## Quick Reference

| Flag | What It Catches |
|------|----------------|
| `strictNullChecks` | null/undefined on non-nullable types |
| `noUncheckedIndexedAccess` | Unsafe array/record access |
| `exactOptionalPropertyTypes` | Explicit undefined on optional props |
| `noImplicitAny` | Missing type annotations |
| `useUnknownInCatchVariables` | Untyped catch variables |
| `noPropertyAccessFromIndexSignature` | Forces bracket notation for dynamic keys |

Narrowing priority: `typeof` > `in` > `instanceof` > type predicates > assertion functions.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.