515

Does anyone know the difference between String and string in TypeScript? Am I correct in assuming that they ought to be the same?

var a: String = "test";
var b: string = "another test";
a = b;
b = a; // this gives a compiler error!

Current version of the compiler says:

Type 'String' is not assignable to type 'string'.
  'string' is a primitive, but 'String' is a wrapper object.
     Prefer using 'string' when possible.

Is that a bug?

Paolo
  • 20,112
  • 21
  • 72
  • 113
Paul0515
  • 23,515
  • 9
  • 32
  • 47
  • 8
    I think "is that a bug" is really a good philosophical question. It's probably "intended" to be so but it creates confusion and compile errors. I think it's at least a problem. – Gherman May 19 '20 at 13:35
  • 1
    Simple distinction would be typeof these [String and string ] is different so one isn't assignable to another. typeof(String) is Object that's why we can use new String('...') while typeof(string) not object. – Badri Paudel Aug 22 '21 at 12:50

10 Answers10

445

Here is an example that shows the differences, which will help with the explanation.

var s1 = new String("Avoid newing things where possible");
var s2 = "A string, in TypeScript of type 'string'";
var s3: string;

String is the JavaScript String type, which you could use to create new strings. Nobody does this as in JavaScript the literals are considered better, so s2 in the example above creates a new string without the use of the new keyword and without explicitly using the String object.

string is the TypeScript string type, which you can use to type variables, parameters and return values.

Additional notes...

Currently (Feb 2013) Both s1 and s2 are valid JavaScript. s3 is valid TypeScript.

Use of String. You probably never need to use it, string literals are universally accepted as being the correct way to initialise a string. In JavaScript, it is also considered better to use object literals and array literals too:

var arr = []; // not var arr = new Array();
var obj = {}; // not var obj = new Object();

If you really had a penchant for the string, you could use it in TypeScript in one of two ways...

var str: String = new String("Hello world"); // Uses the JavaScript String object
var str: string = String("Hello World"); // Uses the TypeScript string type
Fenton
  • 241,084
  • 71
  • 387
  • 401
  • Thanx for clearing that out. So it's safe to use the primitve type string to avoid possible type conversion problems when using other libs that work with string values (based on the idea that nobody actually uses String (?)). Shouldnt assignments between string and String and viceversa be treated equally though? – Paul0515 Feb 06 '13 at 11:22
  • 1
    It is actually safe to use either as the TypeScript types are stripped out to give you 100% compatible JavaScript (in either ES3 or ES5 flavours, and in version 1 ES6 flavour). I would recommend using the `string` type and a literal initialisation: `var s: string = "My String";`. – Fenton Feb 06 '13 at 11:26
  • for the record, thanks to type-inference, `var s: string = "My String"` is identical to `var s = "My String"` ... also, no matter how many times I read this respond, I'm still not grasping the purpose of the `string` type in TypeScript, since, at the end of the day, `('My String')['constructor'] === String`... – mindplay.dk Nov 01 '13 at 21:07
  • 2
    You would normally add the annotation if you weren't initialising the variable with a value. – Fenton Nov 01 '13 at 23:05
  • 2
    I've added an answer to clarify that "foo" vs new String("foo") isn't a new distinction introduced by TypeScript - I don't think it's helpful to call one a JS type and the other a TS type. – Joe Lee-Moyet Jan 25 '16 at 13:46
  • I feel something important is missing here. When you're reading json data string values in json can be null. You'd use the uppercase String variant rather than the primitive for your models so they can also be null, no? – Placeable Aug 06 '19 at 08:20
88

The two types are distinct in JavaScript as well as TypeScript - TypeScript just gives us syntax to annotate and check types as we go along.

String refers to an object instance that has String.prototype in its prototype chain. You can get such an instance in various ways e.g. new String('foo') and Object('foo'). You can test for an instance of the String type with the instanceof operator, e.g. myString instanceof String.

string is one of JavaScript's primitive types, and string values are primarily created with literals e.g. 'foo' and "bar", and as the result type of various functions and operators. You can test for string type using typeof myString === 'string'.

The vast majority of the time, string is the type you should be using - almost all API interfaces that take or return strings will use it. All JS primitive types will be wrapped (boxed) with their corresponding object types when using them as objects, e.g. accessing properties or calling methods. Since String is currently declared as an interface rather than a class in TypeScript's core library, structural typing means that string is considered a subtype of String which is why your first line passes compilation type checks.

Joe Lee-Moyet
  • 1,804
  • 1
  • 20
  • 24
43

For quick readers:

Don’t ever use the types Number, String, Boolean, Symbol, or Object. These types refer to non-primitive boxed objects that are almost never used appropriately in JavaScript code. (emphasis mine)

Source: https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html

Reed Dunkle
  • 3,408
  • 1
  • 18
  • 29
Javier Aviles
  • 7,952
  • 2
  • 22
  • 28
16

In JavaScript strings can be either string primitive type or string objects. The following code shows the distinction:

var a: string = 'test'; // string literal
var b: String = new String('another test'); // string wrapper object

console.log(typeof a); // string
console.log(typeof b); // object

Your error:

Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.

Is thrown by the TS compiler because you tried to assign the type string to a string object type (created via new keyword). The compiler is telling you that you should use the type string only for strings primitive types and you can't use this type to describe string object types.

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
7

TypeScript: String vs string

Argument of type 'String' is not assignable to parameter of type 'string'.

'string' is a primitive, but 'String' is a wrapper object.

Prefer using 'string' when possible.

demo

String Object

// error
class SVGStorageUtils {
  store: object;
  constructor(store: object) {
    this.store = store;
  }
  setData(key: String = ``, data: object) {
    sessionStorage.setItem(key, JSON.stringify(data));
  }
  getData(key: String = ``) {
    const obj = JSON.parse(sessionStorage.getItem(key));
  }
}

string primitive

// ok
class SVGStorageUtils {
  store: object;
  constructor(store: object) {
    this.store = store;
  }
  setData(key: string = ``, data: object) {
    sessionStorage.setItem(key, JSON.stringify(data));
  }
  getData(key: string = ``) {
    const obj = JSON.parse(sessionStorage.getItem(key));
  }
}

enter image description here

Community
  • 1
  • 1
xgqfrms
  • 10,077
  • 1
  • 69
  • 68
5

Simple answer:

  • string => is a type. e.g. console.log(typeof 'foo') // string
  • String => is an object with some methods to create and manipulate strings.
Masih Jahangiri
  • 9,489
  • 3
  • 45
  • 51
3

JavaScript has 7 primitive types strings, numbers, booleans, null, undefined, symbol, and bigint, The first five have been around since the beginning, The symbol primitive was added in ES2015 and bigint is in the process of being finalized.

Primitives are distinguished from objects by being immutable and not having methods. You might object that strings do have methods

 console.log('primitive'.charAt(3)) // output is "m"

Well, While a string primitive does not have methods, JavaScript also defines a String object type that does. JavaScript freely converts between these types. When you access a method like charAt on a string primitive, JavaScript wraps it in a String object, calls the method, and then throws the object away.

TypeScript models this distinction by having distinct types for the primitives and their object wrappers:

  • string and String
  • number and Number
  • boolean and Boolean
  • symbol and Symbol
  • bigint and BigInt

usually things will work if you use String instead of string, except that in some cases, the compiler will raise an error enter image description here

As you can see, string is assignable to String, but String is not assignable to string.

Follow the advice in the error message and stick with string. All the type declarations that ship with TypeScript use it, as do the typings for almost all other libraries.

WadeeSami
  • 59
  • 4
2
  1. string ==> primitive data type.
  2. String ==> non-primitive. it's an object and has access to String class methods and properties
Dennis
  • 99
  • 4
1

This error message is indicating that you are trying to assign a value of type String to a variable or parameter with type string. In TypeScript, string is a primitive type that represents a sequence of characters, while String is a wrapper object that provides additional methods for working with strings.

The error message is suggesting that you should use the string type instead of String whenever possible, as the string type is more efficient and has fewer associated overhead costs. This is because String is an object, and objects in JavaScript (and therefore TypeScript) are stored on the heap and require additional memory allocation when they are created. In contrast, string values are stored directly on the stack, which makes them more efficient to use.

To fix this error, you will need to ensure that you are using the string type instead of String wherever it is expected. You can do this by simply replacing String with string in your code. For example, if you have a variable with type String, you could change it to have type string like this:

let myString: String = "hello, world!"; // Incorrect
let myString: string = "hello, world!"; // Correct

It is also worth noting that, in general, you should prefer using string over String whenever possible, as it is more efficient and easier to work with.

Mizile
  • 134
  • 1
  • 8
0

Based on my personal reference

Prefer the string over the String