'Differentiate between different Strings in TypeScript

I have a set of Types which are just strings, ie.

type FooId = string
type BarId = string

const callFoo = (id: FooId) => {}

const b: BarId = 'bar'

callFoo(b)

To me, that should error, because I'm passing a BarID when I need to pass a FooID

How can I tell TypeScript to give special meaning to these, essentially, strings?

More context:

import { monotonicFactory } from "ulid";

export type ULID = string;
export const ulid = monotonicFactory() as () => ULID;

type FooId = ULID
type BarId = ULID

They're all ULID's, not just "strings"



Solution 1:[1]

Let's utilize @basarat's TDD book: Nominal Typing

Because you are using strings here, I think the enum method is the best choice:

enum FooBrand { _ = "" }
enum BarBrand { _ = "" }

type FooId = string & FooBrand
type BarId = string & BarBrand

const callFoo = (id: FooId) => {}

const b = 'bar' as BarId

callFoo(b); // now errors

You can read more about other nominal typing methods in the link above.

Playground demo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hittingonme