Advanced TypeScript type-system mechanics — union and intersection types, conditional types with `infer`, mapped types, template literal types, generics and their constraints, index signatures, type assertions, and extracting types from other types (return types, array elements, promise results). Use when designing a complex generic, modeling a type that transforms based on another type, extracting a type from a function or structure with `infer`, or deciding between a type assertion and a real narrowing check.
71
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The type-level mechanics that everything else in this skill family builds on: unions, conditionals, mapped types, template literals, generics, and type-level extraction with infer.
Model the problem in types before reaching for a runtime check — a type that makes an invalid combination unrepresentable is a compile-time guarantee, while a runtime check for the same thing only protects the paths that get exercised. Prefer deriving a type from another type (ReturnType<typeof fn>, a mapped type, a conditional extraction with infer) over hand-writing a parallel type that can drift out of sync with the thing it describes. When a conditional type distributes over a union unexpectedly, that is usually the type system doing exactly what it's told — wrap the checked type in a tuple ([T] extends [U]) to opt out of distribution rather than restructuring the type to dodge it. A type assertion (as) is a claim, not a check; only reach for one when you have already established the fact some other way (e.g. immediately after a runtime guard), never as a way to silence an error you haven't investigated.
Use this skill when:
infer to extract a nested typeas clauseas and a type guard here?"infer (return types, array elements, promise values, tuple destructuring, constructor/instance types).typeof, instanceof, custom predicates) — see the sibling typescript-type-guards skill, which also owns exhaustiveness checking.Partial, Pick, ReturnType as a ready-made utility) — see the sibling typescript-utility-types skill for the applied, ready-to-use versions.typescript-design-patterns skill.Do not use this skill for a runtime check — narrowing a value at runtime with typeof/instanceof/a custom predicate belongs in typescript-type-guards. Do not use it as a substitute for tsc --noEmit; a type that looks correct in isolation can still fail to apply as expected against real call sites.
npx tsc --noEmitnpx tsc --noEmit src/index.tsWHY: an as assertion bypasses the compiler without a matching runtime guarantee; the error it silences almost always points at a type that needs to be modeled more precisely, not asserted away.
BAD:
const id = getValue() as string;GOOD:
type Result = { kind: "ok"; value: string } | { kind: "error"; message: string };
function unwrap(result: Result): string {
if (result.kind === "error") throw new Error(result.message);
return result.value;
}infer or a mapped type could deriveWHY: a hand-written parallel type drifts out of sync with the source it was copied from the first time either one changes.
BAD:
function getUser() { return { id: 1, name: "Alice" }; }
interface User { id: number; name: string; } // duplicates getUser's actual return shapeGOOD:
function getUser() { return { id: 1, name: "Alice" }; }
type User = ReturnType<typeof getUser>; // stays correct if getUser changesWHY: an unconstrained <T> accepts anything, including values the type's own logic assumes won't appear.
BAD:
type PropType<T, K> = T extends { [P in K]: infer V } ? V : never; // K unconstrainedGOOD:
type PropType<T, K extends keyof T> = T extends { [P in K]: infer V } ? V : never;| File | Covers |
|---|---|
references/unions-intersections.md | Union and intersection types |
references/conditional-types.md | Conditional types, infer, distributive behavior |
references/mapped-types.md | Mapped types and key remapping mechanics |
references/template-literal-types.md | Template literal types (e.g. typed route parameters) |
references/generics.md | Generic constraints and type parameters |
references/index-signatures.md | Index signatures and dynamic properties |
references/type-assertions.md | as assertions and type compatibility |
references/infer-extraction.md | Extracting return types, parameters, array elements, promise values, tuple elements, and instance/this types with infer |
a1083f4
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.