TypeScript如何区分指向同一类型的类型别名?
TypeScript同基础类型别名赋值无报错:这是预期行为吗?
你遇到的这个情况确实是TypeScript的预期行为,核心原因和TypeScript的类型系统设计以及类型别名的本质有关,我来给你详细解释:
为什么不会报错?
TypeScript采用的是结构类型系统——简单说就是,只要两个类型的结构完全一致,不管它们的名字叫什么,TypeScript都会认为它们是可以互相兼容的。你定义的Email和Password都是string的类型别名,它们的底层结构完全相同,所以在类型检查时,TypeScript会把它们当成同一个类型对待,自然不会阻止你把Password类型的值赋值给Email类型的变量。
至于你问类型别名是不是“宏”,其实不完全是——宏是预编译阶段的文本替换,但类型别名是TypeScript类型系统的一部分,会参与类型推导和检查。只不过在结构完全等价的情况下,它不会创建出一个全新的、和原类型区分开的类型。
怎么实现真正的类型区分?
如果你希望Email和Password被当成完全独立的类型(即使基础类型都是string),可以用社区常用的**品牌类型(Branded Types)**技巧,给每个类型加一个唯一的“标记”,让它们的结构产生差异:
// 给类型添加唯一的品牌标记,仅存在于类型层面 type Email = string & { __brand: 'Email' }; type Password = string & { __brand: 'Password' }; // 封装创建函数,确保类型转换的安全性 const createEmail = (value: string): Email => { // 这里还可以加入邮箱格式的校验逻辑 return value as Email; }; const createPassword = (value: string): Password => { // 同理,这里可以加入密码强度校验 return value as Password; }; // 调整原函数的实现 const returnsEmail = (): Email => createEmail('email@example.com'); const returnsPassword = (): Password => createPassword('P4ssw0rd'); const email1: Email = createEmail('email@example.com'); // 正常通过 const email2: Email = returnsEmail(); // 正常通过 const email3: Email = returnsPassword(); // 现在会触发类型错误!
通过这种方式,Email和Password虽然在运行时还是普通的字符串,但在类型层面因为多了唯一的__brand属性,TypeScript会认为它们是不同的类型,从而阻止跨类型的赋值操作,满足你想要的静态类型区分需求。
内容的提问来源于stack exchange,提问作者yuhr
相关产品推荐
相关产品推荐

