branded-types

Implements phantom branded types in TypeScript to distinguish semantically different primitives.

Updated Sep 5, 2026
One-click install
npx skills add https://github.com/pohlai88/afenda-xforge-v5 --skill branded-types-pohlai88
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: branded-types
Source: https://github.com/pohlai88/afenda-xforge-v5/tree/main/.agents/skills/branded-types
Command: npx skills add https://github.com/pohlai88/afenda-xforge-v5 --skill branded-types-pohlai88

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? TypeScript's structural typing allows any string or number to be passed where a specific kind of string or number is expected, causing bugs like swapped IDs, unsanitized HTML, or mixed-up units. This Skill adds nominal typing through brands so the compiler rejects semantically wrong values. ## Core Features & Use Cases - Branded Primitive Patterns: Define types like UserId, Email, Meters, or AbsolutePath using intersection types with a phantom _brand property. - Type Guards and Factories: Validate values with type predicates (path is AbsolutePath) or factory functions so only checked values receive the brand. - Use Case: Prevent cross-assignment bugs such as passing a PostId where a UserId is required, unsanitized strings into innerHTML, or swapping distance and time arguments in a speed calculation. ## Quick Start Ask the AI to refactor a function that accepts plain strings or numbers so it uses branded types with a validating type guard instead.

Frequently Asked Questions about branded-types

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create nominal types in TypeScript?

TypeScript uses structural typing, so nominal typing requires branded types: intersect a primitive with a phantom property like string & { _brand: 'userId' }. Values can then only be created through type guards or factory functions, preventing accidental cross-assignment.

What is a branded type in TypeScript?

A branded type is an intersection of a primitive with a phantom property, such as type Meters = number & { _brand: 'meters' }. The brand exists only at compile time, so it adds no runtime overhead while making incompatible values unassignable.

Do branded types add runtime overhead in TypeScript?

No, brands are phantom types that exist only in the type system and are erased at runtime. The intersection property is never actually present on the value, so there is no memory or performance cost.

Why does arithmetic lose the brand on branded numbers?

TypeScript's arithmetic operators return plain number, so operations like d * 2 strip the brand from a branded number. You must re-apply the brand with a cast or factory function after computation.

When should I use branded types instead of type aliases?

Use brands when primitives have different semantic meanings, such as UserId versus PostId or sanitized versus raw HTML. Plain type aliases like type UserId = string do not prevent cross-assignment, while brands make the compiler reject mixed values.