For example, when I write:
type Email = string
type Password = string
const returnsEmail = (): Email => '[email protected]' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password
const email1: Email = '[email protected]' // OK
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // should not be OK but silent
TypeScript 2.8.3 seems to emit no errors here. Is this intended behaviour? TypeScript's "aliases" are just "macros"? I know TypeScript deals with only static typing and not validation (kinds of regex matching, in the case like above), but I think this is the bussiness for the former and should be done, especially if annotations explicitly written.
Yes this is intended behaviour, type alias is called 'alias' precisely for that reason - it does not create a new distinct type.
Also, you probably will be surprised, but in TypeScript two different types are interchangeable if they have the same definition, it's called structural typing:
interface Person {
name: string;
}
interface Pet {
name: string;
}
const p: Pet = {name: 'Rosie'};
const person: Person = p; // no error
For the time being (until nominal types are added to TypeScript), one has to resort to various tricks to make types artificially incompatible. One such trick is called 'branded types' (example here), it works by adding superficial property to the type which is never used in the code, it serves only to make the type incompatible to anything else:
type Email = string & { __emailBrand: any };
type Password = string & { __passwordBrand: any };
const returnsEmail = (): Email => '[email protected]' as Email
const returnsPassword = (): Password => 'P4ssw0rd' as Password
const email1: Email = '[email protected]' as Email;//has to use type assertion here
const email2: Email = returnsEmail() // OK
const email3: Email = returnsPassword() // error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With