2

I had an instance where two properties both had to of "number" and I used one instead of another on an accident. Nothing complained and it took a while to debug these.

I wonder if it is possible to extend basic types to make sure that when I try to assign, for example, the value of type Age to a variable with type Score (both being numbers tired)?

EDIT: Sorry for the original question not having a code sample. Nurbol Alpysbayev correctly interpreted my question and his code sample indeed represents what I wanted to see happening:

type Score = number;
type Age = number;

let score: Score = 999;
let age: Age = 45;

score = age; // I want to have this line to throw an error
pavel_karoukin
  • 286
  • 3
  • 10
  • 1
    Can you please provide code examples to the types you refer to? – Dor Shinar Feb 17 '19 at 15:29
  • 3
    You should show the code of what you are trying to achieve and what you tried – Nurbol Alpysbayev Feb 17 '19 at 15:29
  • It would definitely be better if you showed code for the situation, though I think it's still fairly clear what you're asking. – T.J. Crowder Feb 17 '19 at 15:37
  • Typescript is just a static type checker. It cannot protect you from accidents like the one you mention in your question. Plus, you did not post info about the accident in order to understand what happened and what alternatives may exist. – Chris Tapay Feb 17 '19 at 15:45

1 Answers1

3

The quality of the question could be far better, but I think I understood it.

I believe you did something like this:

type Score = number
type Age = number

let score: Score = 999
let age: Age = 45

score = age // no errors (and it confused you)

Now the answer to your question is: both Age and Score are type aliases of the same type, which is number. The names are just for convenience, that's why they are called aliases in the first place.

So you are using type aliases for a wrong task. If you need to differentiate types, then you have to use interfaces like this:

interface Score {type: 'score', value: number}
interface Age {type: 'age', value: number}

let score: Score = {type: 'score', value: 999}
let age: Age = {type: 'age', value: 45}

score = age // error

However you should know that for data representing Score and Age, you should just leave type number without over-engineering them.

Nurbol Alpysbayev
  • 19,522
  • 3
  • 54
  • 89
  • I read the question differently, that they just had `number` and now want to do something like that `Age` and `Score` you assumed they did, but don't know how. (I've often wanted to do this in other languages, disagree that it's over-engineering -- provided the overhead [on the programmer and on the compiler and runtime] is low, which it never has been to date. :-) I'd love to see something like incompatible type aliases in TypeScript. ) – T.J. Crowder Feb 17 '19 at 15:45
  • @T.J.Crowder the TS team deems this is over-engineering :) Many people ask them to add number ranges that could solve what you are talking about, but so far they don't prioritize this, unfortunately (I also want this feature). – Nurbol Alpysbayev Feb 17 '19 at 15:49
  • @T.J.Crowder Oh I think I got what you really meant, and yes this also would be cool :) You meant that a variable with type alias `A` shouldn't be assignable to a variable of type alias `B`. But I also think this feature really would create more problems than advantages. – Nurbol Alpysbayev Feb 17 '19 at 15:55
  • 2
    @T.J.Crowder two words, branded types https://stackoverflow.com/questions/49260143/how-do-you-emulate-nominal-typing-in-typescript/49260286#49260286 or https://stackoverflow.com/search?tab=votes&q=user%3a125734%20branded%20types – Titian Cernicova-Dragomir Feb 17 '19 at 16:45
  • @TitianCernicova-Dragomir - Very interesting! (I was hoping you'd see this question. :-D ) Though a bit of a pain to work with. – T.J. Crowder Feb 17 '19 at 17:26
  • 2
    @T.J.Crowder did not say it's a silver bulet and I would not use it in every circumstance because it does create some pain in working with it. But it's something to have in the tool bag. I always give as an example the TS compiler itself which uses this approach for paths, which although are strings have more semantic meaning especially for a compiler. – Titian Cernicova-Dragomir Feb 17 '19 at 17:30
  • Sorry about poor quality question. And yes, this is exact interpretation of the problem I had. Branded tires so far look closest to what I need. Thank you! – pavel_karoukin Feb 17 '19 at 20:29