常把字符串搞混:比如ID邮箱混为一谈。品牌类型就是给值“打标签”,把看似同构的原始类型区分开

type Password = string & { __brand: 'password' };

function setPassword(password: Password) {}

const raw = 'secret123';
setPassword(raw); // ❌ 报错
setPassword(raw as Password); // ✅ 通过
type Email = string & { __brand: 'email' };
type Username = string & { __brand: 'username' };

function createEmail(value: string): Email {
  if (!value.includes('@')) throw new Error('Invalid email');
  return value as Email;
}

function sendMessage(to: Email) {
  console.log(`Sending to ${to}`);
}

const email = createEmail('[email protected]');
sendMessage(email); // ✅ 通过
sendMessage('not-an-email'); // ❌ 报错

这样就有了清晰边界:在入口处做一次校验,之后到处都能信任这个类型。