Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String is not string

Tags:

typescript

Thinking of string as String works. However thinking of String as string is broken:

var str1:String = "asdf"; 
var str2:String = new String("asdf");
var str3:string = "asdf";
var str4:string = new String("asdf"); // Error 

Try It

Also:

var interfaceBased:String = "123";
var keywordBased:string ="123";
interfaceBased=keywordBased;
keywordBased=interfaceBased; // Error  

Try It

Is this a known compiler bug?

like image 612
basarat Avatar asked Sep 16 '25 10:09

basarat


2 Answers

String is a Javascript type while string is a Typescript type. I don't think it's a bug so much as a quirk. Mainly because there's absolutely no reason to use the String() constructor over string literals.

See here: Typescript: difference between String and string

like image 88
GJK Avatar answered Sep 19 '25 07:09

GJK


This stems from a JavaScript quirk: there are primitive strings and object strings. A primitive string is, well, your everyday string:

typeof "Hi! I'm a string!"  // => "string"

However, any time you use new, you create an object rather than a primitive:

typeof new String("Hi! I'm a string!")  // => "object"

JavaScript also implicitly creates an object string out of a primitive string whenever you access a property, since only objects can have properties:

var s = "Hi! I'm a string!";
s.property = 6;  // s implicitly coerced to object string, property added
console.log(s.property);  // => undefined
// property was added to the object string, but then the object string was
// discarded as s still contained the primitive string. then s was coerced again
// and the property was missing as it was only added to an object whose reference
// was immediately dropped.

You almost never want an object string because of its quirks (e.g., an empty object string is truthy), so rather than using new String, you almost always want String instead. String without new can even convert an object string back into a primitive string:

typeof String(new String("Hi! I'm a string!"))  // => "string"

I don't know if this issue surfaces in TypeScript, but the primitive/object distinction and especially the truthiness issue becomes very odd with Boolean. For example:

var condition = new Boolean(false);
if(condition) {  // always true; objects are always truthy
    alert("The world is ending!");
}

In short, it's because of the object/primitive distinction. You almost always want primitives where you have the option.

like image 38
icktoofay Avatar answered Sep 19 '25 08:09

icktoofay