Typographie: différence entre String et string

257

Quelqu'un connaît-il la différence entre String et string en TypeScript? Ai-je raison de supposer qu'ils devraient être les mêmes?

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

La version actuelle du compilateur dit:

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

Est-ce un bug?

Paul0515
la source
1
Je pense que "c'est qu'un bug" est vraiment une bonne question philosophique. C'est probablement "prévu", mais cela crée de la confusion et des erreurs de compilation. Je pense que c'est au moins un problème.
Gherman

Réponses:

252

Voici un exemple qui montre les différences, ce qui aidera à l'explication.

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

Stringest le type de chaîne JavaScript, que vous pouvez utiliser pour créer de nouvelles chaînes. Personne ne fait cela car en JavaScript les littéraux sont considérés comme meilleurs, donc s2dans l'exemple ci-dessus crée une nouvelle chaîne sans utiliser le newmot - clé et sans utiliser explicitement l' Stringobjet.

string est le type de chaîne TypeScript, que vous pouvez utiliser pour saisir des variables, des paramètres et des valeurs de retour.

Notes complémentaires...

Actuellement (février 2013) Les deux s1et s2sont valides JavaScript. s3est un TypeScript valide.

Utilisation de String. Vous n'avez probablement jamais besoin de l'utiliser, les littéraux de chaîne sont universellement acceptés comme étant la bonne façon d'initialiser une chaîne. En JavaScript, il est également préférable d'utiliser également les littéraux d'objet et les littéraux de tableau:

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

Si vous aviez vraiment un penchant pour la chaîne, vous pouvez l'utiliser dans TypeScript de deux manières ...

var str: String = new String("Hello world"); // Uses the JavaScript String object
var str: string = String("Hello World"); // Uses the TypeScript string type
Fenton
la source
Merci d'avoir effacé cela. Il est donc sûr d'utiliser la chaîne de type primitve pour éviter d'éventuels problèmes de conversion de type lors de l'utilisation d'autres bibliothèques qui fonctionnent avec des valeurs de chaîne (en se basant sur l'idée que personne n'utilise réellement String (?)). Les affectations entre chaîne et chaîne et vice versa ne devraient-elles pas être traitées de la même manière?
Paul0515
1
Il est en fait sûr à utiliser, car les types TypeScript sont supprimés pour vous offrir un JavaScript 100% compatible (dans les versions ES3 ou ES5 et dans la version 1 version ES6). Je recommande d' utiliser le stringtype et une initialisation littérale: var s: string = "My String";.
Fenton
pour l'enregistrement, grâce à l'inférence de type, var s: string = "My String"est identique à var s = "My String"... aussi, peu importe combien de fois j'ai lu cette réponse, je ne comprends toujours pas le but du stringtype dans TypeScript, car, à la fin de la journée , ('My String')['constructor'] === String...
mindplay.dk
2
Vous ajouteriez normalement l'annotation si vous n'initialisiez pas la variable avec une valeur.
Fenton
2
J'ai ajouté une réponse pour préciser que "foo" vs new String ("foo") n'est pas une nouvelle distinction introduite par TypeScript - je ne pense pas qu'il soit utile d'appeler l'un un type JS et l'autre un type TS.
Joe Lee-Moyet
60

Les deux types sont distincts en JavaScript ainsi que TypeScript - TypeScript nous donne juste la syntaxe pour annoter et vérifier les types au fur et à mesure.

Stringfait référence à une instance d'objet qui a String.prototypedans sa chaîne de prototype. Vous pouvez obtenir une telle instance de différentes manières, par exemple new String('foo')et Object('foo'). Vous pouvez tester une instance du Stringtype avec l' instanceofopérateur, par exemple myString instanceof String.

stringest l'un des types primitifs de JavaScript, et les stringvaleurs sont principalement créées avec des littéraux, par exemple 'foo'et "bar", et comme type de résultat de diverses fonctions et opérateurs. Vous pouvez tester le stringtype à l'aide de typeof myString === 'string'.

La grande majorité du temps, stringc'est le type que vous devriez utiliser - presque toutes les interfaces API qui prennent ou retournent des chaînes l'utiliseront. Tous les types primitifs JS seront enveloppés ( encadrés ) avec leurs types d'objets correspondants lors de leur utilisation en tant qu'objets, par exemple en accédant à des propriétés ou en appelant des méthodes. Comme Stringest actuellement déclaré comme une interface plutôt qu'une classe dans la bibliothèque principale de TypeScript , le typage structurel signifie qu'il stringest considéré comme un sous-type, Stringc'est pourquoi votre première ligne passe les vérifications de type de compilation.

Joe Lee-Moyet
la source
2

En JavaScript, les chaînes peuvent être de type primitif de chaîne ou des objets de chaîne. Le code suivant montre la 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

Votre erreur:

Le type 'String' n'est pas assignable au type 'string'. 'string' est une primitive, mais 'String' est un objet wrapper. Préférez utiliser «chaîne» lorsque cela est possible.

Est levé par le compilateur TS parce que vous avez essayé d'affecter le type stringà un type d'objet chaîne (créé via un newmot clé). Le compilateur vous indique que vous devez utiliser le type stringuniquement pour les types primitifs de chaînes et que vous ne pouvez pas utiliser ce type pour décrire les types d'objets chaîne.

Willem van der Veen
la source
1

TypeScript: Stringvsstring

L'argument de type 'String' n'est pas attribuable au paramètre de type 'string'.

'string' est une primitive, mais 'String' est un objet wrapper.

Préférez utiliser «chaîne» lorsque cela est possible.

démo

Objet chaîne

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

chaîne 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));
  }
}

entrez la description de l'image ici

xgqfrms
la source