TypeScript 如何区分指向相同类型的类型别名
例如,当我写到:
type Email = string
type Password = string
const returnsEmail = (): Email => '[email ' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password
const email1: Email = '[email ' // OK
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // should not be OK but silent
TypeScript 2.8.3 在这里似乎没有报错。这是预期行为吗?TypeScript 的“别名”只是“宏”吗?我知道 TypeScript 只处理静态类型而不处理验证(在上面的例子中是正则匹配的类型),但我认为这是前者的职责,特别是当注解明确写出时,应该执行。
答案#1
是的,这是预期的行为,类型别名正是因此被称为“别名”——它不会创建一个新的独立类型。
另外,你可能会感到惊讶,但在 TypeScript 中,如果两个不同的 类型 有相同的定义,它们是可以互换的,这被称为结构类型:
interface Person {
name: string;
}
interface Pet {
name: string;
}
const p: Pet = {name: 'Rosie'};
const person: Person = p; // no error
目前(在 TypeScript 添加名义类型之前),必须使用各种技巧使类型在人工上不兼容。其中一种技巧被称为“品牌类型”(这里有示例),它通过向类型添加在代码中从未使用的表面属性来工作,它仅用于使该类型与其他任何类型不兼容:
type Email = string & { __emailBrand: any };
type Password = string & { __passwordBrand: any };
const returnsEmail = (): Email => '[email ' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password
const email1: Email = '[email ' as Email;//has to use type assertion here
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // error
