常把字符串搞混:比如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'); // ❌ 报错
这样就有了清晰边界:在入口处做一次校验,之后到处都能信任这个类型。