Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does TypeScript consider each number its own type?

The expression 1==2 causes TypeScript to give the error Operator '==' cannot be applied to types '1' and '2'. What are the reasons for TypeScript treating these values as being of a different type (the typeof operator, rather predictably, says that they're both numbers)? Is it a design decision to specifically apply this to numbers, or a byproduct of the overall typing system? What harm could be caused by allowing comparison of literals?

like image 768
clb Avatar asked Aug 31 '17 11:08

clb


People also ask

Why do we need types in TypeScript?

The any type is useful when you don't want to write out a long type just to convince TypeScript that a particular line of code is okay.

What does type mean in TypeScript?

TypeScript - Type Annotations TypeScript is a typed language, where we can specify the type of the variables, function parameters and object properties. We can specify the type using :Type after the name of the variable, parameter or property. There can be a space after the colon.

How many types are there in TypeScript?

The TypeScript has five built-in data types, which are given below.

What represent not having any data type in TypeScript?

Object. object is a type that represents the non-primitive type, i.e. anything that is not number , string , boolean , bigint , symbol , null , or undefined .


3 Answers

1 and 2 in this context are considered so called literal numbers. It means that value 1 has type 1 and thus can only be 1, same with 2. Given that, the expression of 1==2 doesn't make sense because 1 can never be 2, or more precisely their types mismatch, you can't compare apples to oranges.

Here are the rationale and in depth details on where literals types are assumed by default:

  • https://github.com/Microsoft/TypeScript/pull/10676

About literal types:

  • https://github.com/Microsoft/TypeScript/pull/9407
  • https://github.com/Microsoft/TypeScript/pull/5185

One of many examples as to why literal types are useful:

  • https://github.com/Microsoft/TypeScript/pull/9163
like image 54
Trident D'Gao Avatar answered Oct 19 '22 23:10

Trident D'Gao


When TypeScript peforms type inference on the expression 1, it gives it the type 1, not the type number. You can see this if you examine code like this:

const a = 1;

If you use your IDE to query the inferred type of a, you'll see that the type of a is 1. In the TypeScript playground, for instance, you get a tooltip that says const a: 1.

So in if (1 == 2), 1 has type 1 and 2 has type 2. TypeScript does not allow you to compare them because they are of different inferred types. This is part of the type safety TypeScript gives you.

You can work around it with:

if (1 as number == 2) {
}

And you mentioned in a comment that you were doing the 1 == 2 comparison because you could not do if (false) { ... } due to the compiler complaining about unreachable code. I can work around that problem with this:

if (false as boolean) {
    console.log("something");
}
like image 38
Louis Avatar answered Oct 20 '22 00:10

Louis


Typescript can create a type from any constant value. This when combined with union types creates a very powerful way of expressing what a function takes as an argument for example:

function doStuff(p : "yes"| 1| true| "no"| 0| false ){

}

doStuff("maybe"); //Error
doStuff(3); // Error
doStuff(1) ; //OK

You are experiencing the unfortunate side effect that errors such as yours instead of being reports as expression is always false turn into type compatibility errors instead.

like image 33
Titian Cernicova-Dragomir Avatar answered Oct 20 '22 01:10

Titian Cernicova-Dragomir