有人知道TypeScript中String和String的区别吗?我假设它们应该是一样的,对吗?

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

当前版本的编译器说:

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

那是虫子吗?


当前回答

这两种类型在JavaScript和TypeScript中是截然不同的——TypeScript只是提供了注释和检查类型的语法。

String引用具有String的对象实例。原型链中的原型。你可以通过多种方式获得这样的实例,例如new String('foo')和Object('foo')。你可以用instanceof操作符来测试String类型的实例,例如myString instanceof String。

字符串是JavaScript的基本类型之一,字符串值主要是用文字创建的。'foo'和"bar",以及作为各种函数和操作符的结果类型。你可以使用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.

其他回答

对于快速阅读者:

不要使用数字、字符串、布尔、符号或对象类型。这些类型指的是非原始的盒装对象,在JavaScript代码中几乎从来没有适当使用过。(强调我的)

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

简单的回答是:

String =>是一个类型。例如console.log(typeof 'foo') //字符串 String =>是一个具有一些创建和操作字符串的方法的对象。

TypeScript:字符串vs字符串

String类型的实参不能赋值给String类型的形参。 'string'是一个原语,但'string'是一个包装器对象。 尽可能使用'string'。

demo

字符串对象

// 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));
  }
}

字符串的原始

// 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));
  }
}

JavaScript有7种基本类型字符串,数字,布尔值,null, undefined, symbol和bigint,前五种从一开始就存在,符号原语是在ES2015中添加的,bigint正在最终确定的过程中。

原语与对象的区别在于它是不可变的并且没有方法。你可能会反对字符串有方法

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

虽然字符串原语没有方法,但JavaScript也定义了string对象类型。JavaScript可以在这些类型之间自由转换。当您在字符串原语上访问charAt等方法时,JavaScript将其包装在string对象中,调用该方法,然后丢弃该对象。

TypeScript通过为原语及其对象包装器提供不同的类型来模拟这种区别:

字符串和字符串 数目和数目 布尔和布尔 符号与符号 bigint和bigint

通常情况下,如果你使用String而不是String,事情会正常工作,除了在某些情况下,编译器会引发一个错误

如您所见,string可以赋值给string,但string不能赋值给string。

按照错误消息中的建议使用字符串。TypeScript附带的所有类型声明都使用它,几乎所有其他库的类型也是如此。

在JavaScript中,字符串既可以是字符串基本类型,也可以是字符串对象。下面的代码显示了两者的区别:

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

你的错误:

类型'String'不能赋值给类型'String'。'string'是a 但'String'是一个包装器对象。 尽可能使用'string'。

由TS编译器抛出,因为您试图将类型字符串分配给字符串对象类型(通过new关键字创建)。编译器告诉你,你应该只对字符串基本类型使用类型string,你不能用这个类型来描述字符串对象类型。