typescript-strict
TypeScript Strict Patterns
Strict Configuration
// tsconfig.json essentials
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
Interface vs Type
// Use interface for objects that may be extended
interface Service {
slug: string;
name: string;
price: number;
}
interface PremiumService extends Service {
benefits: string[];
}
// Use type for unions, primitives, tuples
type Locale = 'pt-PT' | 'en' | 'tr' | 'es' | 'fr' | 'de';
type DeliveryMode = 'in-person' | 'online' | 'both';
type Coordinates = [number, number];
Type Guards
// Custom type guard
function isService(value: unknown): value is Service {
return (
typeof value === 'object' &&
value !== null &&
'slug' in value &&
'name' in value
);
}
// Discriminated unions
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: Result<T>) {
if (result.success) {
console.log(result.data); // TypeScript knows data exists
} else {
console.error(result.error); // TypeScript knows error exists
}
}
Generic Patterns
// Generic data fetcher
async function fetchData<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) throw new Error('Failed to fetch');
return res.json() as Promise<T>;
}
// Generic component props
interface ListProps<T> {
items: T[];
renderItem: (item: T, index: number) => React.ReactNode;
keyExtractor: (item: T) => string;
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item, i) => (
<li key={keyExtractor(item)}>{renderItem(item, i)}</li>
))}
</ul>
);
}
Utility Types
// Partial - all properties optional
type ServiceUpdate = Partial<Service>;
// Required - all properties required
type RequiredService = Required<Service>;
// Pick - select specific properties
type ServicePreview = Pick<Service, 'slug' | 'name'>;
// Omit - exclude properties
type ServiceWithoutPrice = Omit<Service, 'price'>;
// Record - key-value mapping
type LocaleMessages = Record<Locale, Record<string, string>>;
// Extract/Exclude for unions
type OnlineDelivery = Extract<DeliveryMode, 'online' | 'both'>;
Nullable Handling
// Non-null assertion (use sparingly)
const element = document.getElementById('root')!;
// Optional chaining + nullish coalescing
const name = user?.profile?.name ?? 'Anonymous';
// Type narrowing
function processValue(value: string | null | undefined) {
if (value == null) return; // Handles both null and undefined
console.log(value.toUpperCase()); // value is string
}
Component Props Patterns
// Props with children
interface ContainerProps {
children: React.ReactNode;
className?: string;
}
// Props extending HTML elements
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary';
loading?: boolean;
}
// Polymorphic component
interface BoxProps<T extends React.ElementType> {
as?: T;
children: React.ReactNode;
}
type BoxPropsWithRef<T extends React.ElementType> = BoxProps<T> &
Omit<React.ComponentPropsWithoutRef<T>, keyof BoxProps<T>>;
Const Assertions
// Immutable arrays and objects
const LOCALES = ['pt-PT', 'en', 'tr', 'es', 'fr', 'de'] as const;
type Locale = typeof LOCALES[number]; // 'pt-PT' | 'en' | ...
const THEME_CONFIG = {
studio: { bg: '#ffffff', accent: '#000000' },
earth: { bg: '#faf9f6', accent: '#8b7355' },
} as const;
Zod Integration
import { z } from 'zod';
// Infer types from Zod schemas
const ServiceSchema = z.object({
slug: z.string(),
name: z.string(),
price: z.number().positive(),
});
type Service = z.infer<typeof ServiceSchema>;
More from canatufkansu/claude-skills
next-intl-i18n
next-intl internationalization for 6 locales (pt-PT, en, tr, es, fr, de) with locale-prefixed routing, useTranslations/getTranslations patterns, and message file structure. Use when adding translations, creating localized pages, implementing language switchers, or handling locale routing.
42sitemap-robots
Automated sitemap generation for all locale URLs, robots.txt configuration, and llms.txt for AI crawler optimization. Use when setting up sitemap.xml, configuring crawling rules, or improving discoverability for search engines and AI systems.
35tailwind-shadcn
Tailwind CSS utility patterns with shadcn/ui component usage, theming via CSS variables, and responsive design. Use when styling components, installing shadcn components, implementing dark mode, or creating consistent design systems.
29json-ld-schemas
JSON-LD structured data for Organization, Person, Service, Product, FAQPage, and BreadcrumbList with reusable components. Use when implementing schema.org markup, adding rich snippets, or improving search engine understanding of page content.
22framer-motion-animations
Subtle animation patterns for hero sections, card reveals, page transitions, and scroll-triggered effects using Framer Motion. Use when adding animations to components, implementing scroll effects, or creating page transitions.
22responsive-mobile-first
Mobile-first responsive patterns with sticky headers, floating CTAs, accessible navigation, and touch-friendly interactions. Use when implementing responsive layouts, mobile navigation, or ensuring touch-friendly UI.
12