class UserId { constructor(public value: string) {} }
class OrderId { constructor(public value: string) {} }
function loadOrder(id: OrderId): void { /* ... */ }
loadOrder(new UserId("u_1"));
No error: it compiles
It compiles. TypeScript uses structural typing: it compares the shape of types, not their names. Both classes have exactly one public value: string, so a UserId fits where an OrderId is expected.
"Error: UserId is not assignable to OrderId" is what Java or C# would say, because they compare names. To make TypeScript tell them apart, add a private member (for example private readonly brand = "OrderId") or use a branded type.