Type design philosophy required in the TypeScript 5.x era
TypeScript 5 series introduced a number of new features that maximize the accuracy of type inference without compromising the developer experience. Code that relies on excessive type assertions (as) is a breeding ground for run-time errors. With the kata system on your side, we will explain practical techniques that will naturally narrow down your kata.
1. const type parameter: smarter literal type inference
Previously, if you wanted to preserve literal types in function arguments, you had to add as const on the caller side. TypeScript 5.0’s const type parameter allows you to force literal inference on the function definition side.
// 呼び出し側の as const なしで厳密なリテラル配列として推論
function createRoutes<const T extends readonly string[]>(routes: T): T {
return routes;
}
const routes = createRoutes(['/home', '/dashboard']);
Arrays and objects passed as arguments are not widened and are safely inferred as exact tuples or literals.
2. satisfies operator: Compatibility of type compatibility verification and inference
satisfies solves the dilemma that adding a type annotation causes the property’s concrete type information to be lost, and removing it causes validation to fail.
type Palette = Record<string, string | number[]>;
const theme = {
primary: '#0066cc',
rgb: [0, 102, 204],
} satisfies Palette;
// 型制約を満たしつつ、個別プロパティの型が完全保持される
theme.primary.toUpperCase(); // string型メソッドが安全に呼出可能
3. Event hub with template literal types
type Event = 'click' | 'focus';
type HandlerMap = { [K in `on${Capitalize<Event>}`]?: () => void };
Enforce string concatenation rules at the type level and prevent 100% typos in event names at build time.
Anti-pattern: “Any” that should be eradicated in the field
Using as any as a quick way to resolve type errors is a bad way to forego the benefits of TypeScript. Use type guard functions (the is operator) and schema validators such as Zod to safely narrow down types at runtime boundaries.

