Typescript: number data type implements or not a Number type?

Created on 19 Aug 2017  路  3Comments  路  Source: microsoft/TypeScript

For its language segment I'm writing a detailed tutorial for TypeScript.
But there is one thing that I cannot understand. The data type t implements the data type T?
Or the data type of t compatible with the data type T?
(t === number, string, boolean, symbol, object)
(T === Number, String, Boolean, Symbol, Object)

Question

Most helpful comment

Thanks for the awesome explanation @aluanhaddad.

To add to this, these are also called "wrapper objects", and are used to provide the methods and properties on each primitive.

So for instance, to evaluate "Hello!".toLowerCase(), ECMAScript will first try to convert "Hello!" to an object (String) before fetching a property named toLowerCase.

That's why in TypeScript, we use these types to know what methods string, number, and boolean have.

All 3 comments

The types number, string, boolean, and symbol are the types of values of literals of each of their respective types as well as operators on those types and various conversions.
For example:

"hello world" // literal -> type of expression is string
var s = "hello world"; // -> type of s is string

These types also arise from operations that perform conversions
For example:

+"12" //  literal (type string) converted via `+`-> expression has type number

Another way to write the above is to invoke the JavaScript built in function object Number

Numer("12") // literal (type string) converted by calling `Number`-> expression has type number

All of these uses are fine and all produce values of types corresponding to the lowercase variants.

However, where the uppercase variants come into play is when certain JavaScript built in function objects such as the above Number, are invoked with new.
For example:

new Number("12") // literal (type string) as ctor arg of `Number`-> expression has type Number

These create wrapper objects that have reference identity. They are different types than their literal counterparts.
For example:

1 === 1
new Number(1) !== 1
new Number(1) !== new Number(1)

In typescript, the name of the type of a value created by "newing" a function or class is the name of that function or class.

The uppercase Number type exists to represent the objects created by invoking Number as a constructor. These objects have different, and in general highly undesirable behavior such as the equality relation shown above.

In practice, the uppercase types should _never_ be used because they represent the values produced by by invoking objects like Number as constructors and this should not be done.

Notice how invoking Number without new results in a number, but invoking it with new results in a Number.

A Number is never what you want.

While some might wish to postrationalize this behavior of the JavaScript builtin Number by claiming that enabling subclassing was the goal (something still not viable), I personally think that the behavior may be bad legacy that JavaScript inherited from Java.

The same holds for String, Boolean.

While JavaScript has a built in Symbol function object as well, it does not suffer from these problems because it cannot be invoked with new. It refers to the prototype of all symbol values. These values are of type symbol.

Object is different in that it refers to the type created by an object literal expression, calling the JavaScript builtin Object, and invoking that builtin with new. In this case new does not change the effect, and produces the same result as normal invocation.

TypeScript introduced the object type, to represent the super type or shape, of objects that are _not_ primitives (strings, numbers, booleans, etc) but are not known to have any properties beyond those inherited via Object.prototype.

Thanks for the awesome explanation @aluanhaddad.

To add to this, these are also called "wrapper objects", and are used to provide the methods and properties on each primitive.

So for instance, to evaluate "Hello!".toLowerCase(), ECMAScript will first try to convert "Hello!" to an object (String) before fetching a property named toLowerCase.

That's why in TypeScript, we use these types to know what methods string, number, and boolean have.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Was this page helpful?
0 / 5 - 0 ratings