원클릭으로
typescript-strict-patterns
TypeScript strict mode patterns, branded types, discriminated unions, and type-safe architecture for MCP servers
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
TypeScript strict mode patterns, branded types, discriminated unions, and type-safe architecture for MCP servers
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
C4 architecture model, security architecture, Mermaid diagrams, SECURITY_ARCHITECTURE.md, and comprehensive documentation per Hack23 Secure Development Policy
AI-augmented development controls, GitHub Copilot governance, LLM security, AI-generated code review per Hack23 Secure Development Policy
EU AI Act compliance, OWASP LLM security, responsible AI practices for parliamentary data and MCP server applications
Enforce code quality with ESLint, TypeScript strict mode, Knip unused detection, and quality gates for MCP servers
ISO 27001, NIST CSF 2.0, CIS Controls v8.1, EU CRA compliance mapping, multi-standard alignment per Hack23 ISMS policies
Contribution process with PR workflow, code review standards, commit conventions, and open source best practices
| name | typescript-strict-patterns |
| description | TypeScript strict mode patterns, branded types, discriminated unions, and type-safe architecture for MCP servers |
| license | MIT |
This skill applies when:
TypeScript strict mode is enabled in this project with strictNullChecks, noImplicitAny, and noUncheckedIndexedAccess. All code must comply with these strict rules.
any: Use unknown for truly dynamic types, then narrow with type guardsz.infer<>: Derive TypeScript types from Zod schemasinterface for Objects: Use type for unions, aliases, mapped typesas const: For literal types and readonly valuesimport { z } from 'zod';
// Branded type for MEP IDs (prevents mixing with other IDs)
const MEP_ID = z.number().int().positive().brand<'MEP_ID'>();
type MEP_ID = z.infer<typeof MEP_ID>;
// Branded type for Document IDs
const DocumentIDSchema = z.string()
.regex(/^EP-\d{8}-\d{5}$/)
.brand<'DocumentID'>();
type DocumentID = z.infer<typeof DocumentIDSchema>;
// Type safety: Can't mix IDs
function getMEP(id: MEP_ID): Promise<MEP> { /* ... */ }
function getDocument(id: DocumentID): Promise<Document> { /* ... */ }
const mepId: MEP_ID = MEP_ID.parse(12345);
const docId: DocumentID = DocumentIDSchema.parse('EP-20240101-00001');
await getMEP(mepId); // ✅ Works
await getDocument(docId); // ✅ Works
// await getMEP(docId); // ❌ Type error: DocumentID not assignable to MEP_ID
/**
* Discriminated union for type-safe question handling
*/
interface WrittenQuestion {
type: 'written';
id: string;
questionText: string;
answerText?: string;
}
interface OralQuestion {
type: 'oral';
id: string;
questionText: string;
sessionDate: string;
}
interface PriorityQuestion {
type: 'priority';
id: string;
questionText: string;
deadline: string;
}
type ParliamentaryQuestion = WrittenQuestion | OralQuestion | PriorityQuestion;
// Type-safe handling with exhaustive checking
function processQuestion(q: ParliamentaryQuestion): string {
switch (q.type) {
case 'written':
return `Written: ${q.answerText || 'pending'}`;
case 'oral':
return `Oral on ${q.sessionDate}`;
case 'priority':
return `Priority, deadline: ${q.deadline}`;
default:
// TypeScript ensures all cases handled
const _exhaustive: never = q;
return _exhaustive;
}
}
import { z } from 'zod';
// Define Zod schema (runtime validation)
const MEPSchema = z.object({
id: z.number().int().positive(),
fullName: z.string().min(1).max(255),
country: z.string().length(2),
partyGroup: z.string().min(1).max(50),
active: z.boolean(),
termStart: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
termEnd: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
committees: z.array(z.string()).default([]),
}).strict();
// Infer TypeScript type from schema
type MEP = z.infer<typeof MEPSchema>;
// Use in function
function validateMEP(data: unknown): MEP {
return MEPSchema.parse(data);
}
interface MEP {
id: number;
fullName: string;
country: string;
partyGroup: string;
email?: string;
phone?: string;
}
// Pick specific fields
type MEPSummary = Pick<MEP, 'id' | 'fullName' | 'country'>;
// Omit sensitive fields
type PublicMEP = Omit<MEP, 'email' | 'phone'>;
// All fields optional (for updates)
type MEPUpdate = Partial<MEP>;
// All fields required
type CompleteMEP = Required<MEP>;
// Record type for mapping
type MEPMap = Record<number, MEP>;
// Readonly (immutable)
type ImmutableMEP = Readonly<MEP>;
// Handle nullable types explicitly
function getCommitteeName(mep: MEP, committeeCode?: string): string | null {
if (!committeeCode) {
return null;
}
const committee = mep.committees?.find(c => c.code === committeeCode);
if (!committee) {
return null;
}
return committee.name;
}
// Non-null assertion only when certain
function getRequiredField(data: { field?: string }): string {
// Only use ! when you're absolutely certain
return data.field!; // Throws if field is undefined
}
// Better: Validate and throw explicit error
function getRequiredFieldSafe(data: { field?: string }): string {
if (!data.field) {
throw new ValidationError('field is required');
}
return data.field;
}
/**
* Generic API response wrapper
*/
interface APIResponse<T> {
data: T;
status: number;
cached: boolean;
latency: number;
}
// Usage
async function fetchMEP(id: number): Promise<APIResponse<MEP>> {
const startTime = Date.now();
const mep = await getMEP(id);
return {
data: mep,
status: 200,
cached: false,
latency: Date.now() - startTime,
};
}
/**
* Generic cache interface
*/
interface Cache<K, V> {
get(key: K): V | undefined;
set(key: K, value: V): void;
has(key: K): boolean;
delete(key: K): boolean;
clear(): void;
}
any// NEVER - loses all type safety!
function bad(data: any): any {
return data.something.nested.value; // No type checking!
}
// GOOD - use unknown and type guards
function good(data: unknown): string {
if (typeof data === 'object' && data !== null && 'value' in data) {
return String(data.value);
}
throw new Error('Invalid data structure');
}
// NEVER - return type unclear!
function bad(id: number) {
return getMEP(id); // What type is returned?
}
// GOOD - explicit return type
function good(id: number): Promise<MEP> {
return getMEP(id);
}
// NEVER - may crash!
function bad(mep: MEP): string {
return mep.email.toLowerCase(); // email is optional!
}
// GOOD - handle nullable
function good(mep: MEP): string | null {
return mep.email?.toLowerCase() ?? null;
}
/**
* Type guard for MEP
*/
function isMEP(value: unknown): value is MEP {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
typeof value.id === 'number' &&
'fullName' in value &&
typeof value.fullName === 'string'
);
}
// Usage
function processMEP(data: unknown): void {
if (isMEP(data)) {
// TypeScript knows data is MEP here
console.log(data.fullName);
}
}
/**
* Make all properties of T nullable
*/
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type NullableMEP = Nullable<MEP>;
// Result: { id: number | null; fullName: string | null; ... }
/**
* Make specific properties optional
*/
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type MEPWithOptionalEmail = PartialBy<MEP, 'email' | 'phone'>;
const Assertions: For literal types (as const)asPrimary:
Related:
import type for minimal runtime footprint