Opaque String Type
An opaque string type in TypeScript is a way to create nominally typed strings. Nominally typed strings are strings that are distinguishable from other strings even though they have the same underlying type. This helps prevent accidental misuse of different kinds of strings (like IDs or tokens).
Concept
In TypeScript, all plain strings are treated the same. So if you have multiple different string values like UserId, OrderId, etc., TypeScript won’t stop you from mixing them up even if that causes bugs.
function getUserName(userId: string): string {
return `Name for user ${userId}`;
}
function getOrderDetails(orderId: string): string {
return `Details for order ${orderId}`;
}
const userId = "user-123";
const orderId = "order-456";
// Accidentally passing orderId to getUserName – no error!
getUserName(orderId); //Logically incorrect, but compiles!
// TypeScript doesn't know these strings have different meanings. it only sees string.
The key idea is to Use type branding or opaque types to make a string unique by attaching a “tag.” This makes types that are not interchangeable, even though they’re both based on string.
Example
type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };
function createUserId(id: string): UserId {
return id as UserId;
}
function createOrderId(id: string): OrderId {
return id as OrderId;
}
function getUserName(userId: UserId): string {
return `Name for user ${userId}`;
}
function getOrderDetails(orderId: OrderId): string {
return `Details for order ${orderId}`;
}
const userId = createUserId("user-123");
const orderId = createOrderId("order-456");
getUserName(userId); // OK
getOrderDetails(orderId); // OK
getUserName(orderId); // Type Error! Can't mix up types now
This is a short summary of what I understood. Please refer to this article for more details.