3 ms·
I would love to see an extended example. When I tried this in typescript 2.6 it still made PaymentAmount and AccountNumber equivalent types.
by koblas 9y ago
I would love to see an extended example. When I tried this in typescript 2.6 it still made PaymentAmount and AccountNumber equivalent types.
- saurik 9y agoI have not tried it yet, but this technique is documented as the second pattern on this website: https://basarat.gitbooks.io/typescript/docs/tips/nominalTyping.html https://basarat.gitbooks.io/typescript/docs/tips/nominalTypi... (edit:) Ah ha! "Because numbers are type compatible with enums the previous technique cannot be used for them."
- justhelpingout 9y agoYou can certainly do this - you just need something to contain the enum since an enum is a nominal subtype of `number` already, so TypeScript unifies `number & anyEnum` to `number`. The best tagging mechanism these days is `Nominal<T>` (which has no emit) or `As<T>` (which has a minimal amount of emit): interface Nominal<T> { 'nominal type tag': T } class As<T> { private tag: T } Both are used in the same manner: const enum SomeTag { } type Something = number & As<SomeTag> // or type Something = number & Nominal<SomeTag> You can even avoid the boilerplate of `const enum` if you make the `T` of `As` or `Nominal` `T extends string`: type Something = number & As<'some:unique:string:tag'> In both cases, the values are not unified, so: type Something = number & As<'kind1'> type SomethingElse = number & As<'kind2'> var x: Something = 123 as Something; var y: SomethingElse = 456 as SomethingElse; x = y; // Type 'SomethingElse' is not assignable to type 'Something'.
- TomMarius 9y agoBTW the minimal emit of the class-based example will be removed by Webpack since the runtime representation is never used. Best option if you use a bundler.