TypeScript如何区分引用相同类型的类型别名

时间:2018-05-11 21:48:19

标签: typescript

例如,当我写:

type Email = string
type Password = string

const returnsEmail = (): Email => 'email@example.com' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password

const email1: Email = 'email@example.com' // OK
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // should not be OK but silent

TypeScript 2.8.3似乎在这里没有发出任何错误。这是预期的行为吗? TypeScript" s"别名"只是"宏"?我知道TypeScript只处理静态类型而不是验证(在上面的情况下是正则表达式匹配的种类),但我认为这是前者的业务,应该完成,特别是如果明确写入注释。

1 个答案:

答案 0 :(得分:2)

是的,这是预期的行为,因为这个原因,类型别名被称为'别名' - 它不会创建新的不同类型。

此外,您可能会感到惊讶,但在TypeScript中,如果它们具有相同的定义,则两个不同的类型是可互换的,它被称为structural typing

interface Person {
    name: string;
}

interface Pet {
    name: string;
}

const p: Pet = {name: 'Rosie'};

const person: Person = p; // no error

目前(直到将名义类型添加到TypeScript中),必须采用各种技巧来使类型人为地不兼容。一个这样的技巧叫做“branded types”(example here),它通过向代码中从不使用的类型添加表面属性来工作,它仅用于使类型与其他任何东西不兼容:< / p>

type Email = string & { __emailBrand: any };
type Password = string & { __passwordBrand: any };

const returnsEmail = (): Email => 'email@example.com' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password

const email1: Email = 'email@example.com' as Email;//has to use type assertion here
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // error