Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

7 TypeScript Patterns I Use in Every Project

7 TypeScript Patterns I Use in Every Project These aren't groundbreaking. They're the boring patterns that prevent bugs and save hours of debugging. 1. The Result Type (No More try/catch Hell) // Instead of throwing…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




7 TypeScript Patterns I Use in Every Project



These aren't groundbreaking. They're the boring patterns that prevent bugs and save hours of debugging.






1. The Result Type (No More try/catch Hell)






// Instead of throwing exceptions everywhere:
function divide(a: number, b: number): number {
if (b === 0) throw new Error("Division by zero");
return a / b;
}

// Use a Result type:
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E };

function divide(a: number, b: number): Result<number, string> {
if (b === 0) return { ok: false, error: "Division by zero" };
return { ok: true, value: a / b };
}

// Usage — the compiler FORCES you to handle errors:
const result = divide(10, 0);
if (result.ok) {
console.log(result.value); // TypeScript knows this is number
} else {
console.error(result.error); // TypeScript knows this is string
}






Why this matters: No more "undefined is not a function" because you forgot a try/catch. The type system enforces error handling.






2. Branded Types (Prevent Mixing Up IDs)






// The problem:
function getUser(id: string) { /* ... */ }
function getPost(id: string) { /* ... */ }

// Easy to mix up:
getUser(postId); // TypeScript allows this! But it's wrong!

// The fix — branded types:
type UserId = string & { readonly __brand: 'UserId' };
type PostId = string & { readonly __brand: 'PostId' };

function createUser(id: string): UserId {
return id as UserId;
}

function getUser(id: UserId) { /* ... */ }
function getPost(id: PostId) { /* ... */ }

const userId = createUser('abc');
getUser(userId); // ✅ Works
// getPost(userId); // ❌ TypeScript error! Type 'UserId' is not assignable to 'PostId'






When to use: Anytime you have multiple IDs that look the same (userId, orderId, sessionId) but mean different things.






3. The Builder Pattern for Complex Objects






interface Config {
host: string;
port: number;
database: string;
ssl: boolean;
poolSize: number;
timeout: number;
}

class ConfigBuilder {
private config: Partial<Config> = {};

static create() {
return new ConfigBuilder();
}

withHost(host: string) {
this.config.host = host;
return this; // Chain!
}

withPort(port: number) {
this.config.port = port;
return this;
}

withDatabase(database: string) {
this.config.database = database;
return this;
}

withSSL(ssl = true) {
this.config.ssl = ssl;
return this;
}

withPoolSize(size: number) {
this.config.poolSize = size;
return this;
}

build(): Config {
if (!this.config.host) throw new Error('host is required');
if (!this.config.database) throw new Error('database is required');

return {
host: this.config.host,
port: this.config.port ?? 5432,
database: this.config.database,
ssl: this.config.ssl ?? false,
poolSize: this.config.poolSize ?? 10,
timeout: this.config.timeout ?? 5000,
};
}
}

// Usage — readable, flexible, with defaults:
const config = ConfigBuilder.create()
.withHost('localhost')
.withDatabase('myapp')
.withSSL()
.withPoolSize(20)
.build();









4. Strict Event Emitter Types






// Instead of the loose EventEmitter from Node:
import { EventEmitter } from 'events';

const emitter = new EventEmitter();
emitter.on('data', (payload: unknown) => { /* type safety? nah */ });
emitter.emit('data', 123); // No type check
emitter.emit('typo', 'anything'); // No type check

// Strict typed version:
type EventMap = {
'user:login': { userId: string; timestamp: Date };
'user:logout': { userId: string };
'error': { message: string; code: number };
'data:update': { key: string; value: unknown };
};

class TypedEmitter<Events extends Record<string, unknown>> {
private emitter = new EventEmitter();

on<K extends keyof Events & string>(
event: K,
handler: (payload: Events[K]) => void
) {
this.emitter.on(event, handler as (...args: unknown[]) => void);
return () => this.emitter.off(event, handler as (...args: unknown[]) => void);
}

emit<K extends keyof Events & string>(
event: K,
payload: Events[K]
) {
this.emitter.emit(event, payload);
}
}

// Usage — fully typed:
const bus = new TypedEmitter<EventMap>();

bus.on('user:login', (payload) => {
console.log(payload.userId); // TypeScript knows this is string
console.log(payload.timestamp); // TypeScript knows this is Date
});

bus.on('error', (payload) => {
console.log(payload.code); // TypeScript knows this is number
});

// bus.emit('user:login', { userId: 123 }); // ❌ Error: string expected
// bus.emit('nonexistent', {}); // ❌ Error: not in EventMap









5. The Guard Pattern (Narrow Types in Functions)






interface User {
id: string;
name: string;
role: 'admin' | 'editor' | 'viewer';
email?: string; // Might not be set
}

// Instead of checking everywhere:
function sendEmail(user: User) {
if (!user.email) throw new Error('No email');
// TypeScript still thinks email might be undefined here in some cases
}

// Use type guards:
function hasEmail(user: User): user is User & { email: string } {
return typeof user.email === 'string' && user.email.length > 0;
}

function isAdmin(user: User): user is User & { role: 'admin' } {
return user.role === 'admin';
}

// Now TypeScript knows:
function sendEmail(user: User) {
if (!hasEmail(user)) return; // Guard clause
console.log(user.email.toLowerCase()); // ✅ TypeScript knows email is string
}

function deleteEverything(user: User) {
if (!isAdmin(user)) throw new Error('Unauthorized');
// ✅ TypeScript knows role is 'admin' here
}









6. Zod for Runtime Validation






import { z } from 'zod';

// Define schema once — use for both types AND runtime validation
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
role: z.enum(['admin', 'editor', 'viewer']),
createdAt: z.string().datetime(),
});

// Infer TypeScript type from schema
type User = z.infer<typeof UserSchema>;

// Validate API responses at runtime:
async function fetchUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();

// This throws if data doesn't match schema
return UserSchema.parse(data);
}

// Safe parse (doesn't throw):
const result = UserSchema.safeParse(mysteryData);
if (result.success) {
const user: User = result.data;
} else {
console.error(result.error.flatten());
}






Why Zod over Joi/ Yup? Type inference. Your schema IS your type definition. No duplication.






7. The Async Pool Pattern






// When you need to run many async operations but limit concurrency:
async function asyncPool<T>(
concurrency: number,
items: T[],
fn: (item: T, index: number) => Promise<void>
): Promise<void> {
const executing = new Set<Promise<void>>();

for (const [index, item] of items.entries()) {
const promise = fn(item, index).then(() => {
executing.delete(promise);
});
executing.add(promise);

if (executing.size >= concurrency) {
await Promise.race(executing);
}
}

await Promise.all(executing);
}

// Usage — fetch 100 URLs but only 5 at a time:
const urls = Array.from({ length: 100 }, (_, i) => `https://api.example.com/page/${i}`);

await asyncPool(5, urls, async (url) => {
const response = await fetch(url);
if (!response.ok) console.error(`Failed: ${url}`);
});

// Compare with naive approach (all at once — might crash):
// await Promise.all(urls.map(url => fetch(url))); // 💥 Too many connections









Bonus: The Never-Returning Function






// For functions that always throw (assertions, unreachable code):
function assert(condition: unknown, message: string): asserts condition {
if (!condition) throw new Error(message);
}

function unreachable(x: never): never {
throw new Error(`Unreachable code reached: ${x}`);
}

// Usage:
type Status = 'loading' | 'success' | 'error';

function handleStatus(status: Status): string {
switch (status) {
case 'loading': return 'Loading...';
case 'success': return 'Done!';
case 'error': return 'Failed!';
}
// If you add a new status type, TypeScript will error here
// because the switch is no longer exhaustive
}









Which patterns do you use daily? Drop your favorites in the comments.



Follow @armorbreak for more TypeScript and Node.js content.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten 7 TypeScript Patterns I Use in Every Project

Thematisch verwandte Begriffe: TypeScript, Patterns, Every, Project · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94097 | A vulnerability was determined in Netcore NBR200V2 1.3.241127.071246. Th…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick