Maszynopis: różnica między ciągiem a ciągiem

255

Czy ktoś zna różnicę między ciągiem a ciągiem w TypeScript? Czy mam rację zakładając, że powinny być takie same?

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

Obecna wersja kompilatora mówi:

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

Czy to błąd?

Paul0515
źródło
1
Myślę, że „czy to błąd” to naprawdę dobre pytanie filozoficzne. Prawdopodobnie jest to „zamierzone”, ale powoduje zamieszanie i błędy kompilacji. Myślę, że to przynajmniej problem.
Gherman

Odpowiedzi:

251

Oto przykład, który pokazuje różnice, które pomogą w wyjaśnieniu.

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

Stringjest typem ciągu znaków JavaScript, którego można użyć do tworzenia nowych ciągów znaków. Nikt tego nie robi, ponieważ w JavaScript literały są uważane za lepsze, więc s2w powyższym przykładzie tworzy nowy ciąg bez użycia newsłowa kluczowego i bez jawnego użycia Stringobiektu.

string to typ ciągu TypeScript, którego można używać do wpisywania zmiennych, parametrów i zwracanych wartości.

Dodatkowe uwagi ...

Obecnie (luty 2013), Obie s1i s2obowiązują JavaScript. s3jest poprawnym TypeScript.

Korzystanie z String. Prawdopodobnie nigdy nie musisz go używać, literały łańcuchowe są powszechnie akceptowane jako właściwy sposób inicjowania łańcucha. W JavaScript uważa się również, że lepiej używać literałów obiektowych i literałów tablicowych:

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

Jeśli naprawdę masz skłonność do łańcucha, możesz go użyć w TypeScript na jeden z dwóch sposobów ...

var str: String = new String("Hello world"); // Uses the JavaScript String object
var str: string = String("Hello World"); // Uses the TypeScript string type
Fenton
źródło
Dzięki za wyjaśnienie tego. Dlatego bezpiecznie jest używać łańcucha typu primitve, aby uniknąć możliwych problemów z konwersją typu podczas korzystania z innych bibliotek lib, które działają z wartościami łańcucha (w oparciu o ideę, że nikt tak naprawdę nie używa łańcucha (?)). Czy przypisania między ciągiem znaków i ciągiem znaków i odwrotnie nie powinny być jednakowo traktowane?
Paul0515
1
Można go bezpiecznie używać, ponieważ typy TypeScript są usuwane, aby zapewnić w 100% kompatybilny JavaScript (w wersjach ES3 lub ES5 oraz w wersji 1 ES6). Polecam za pomocą stringrodzaju i dosłownego inicjalizacji: var s: string = "My String";.
Fenton
rekord, dzięki wnioskowaniu typu, var s: string = "My String"jest identyczny z var s = "My String"... również, bez względu na to, ile razy przeczytałem tę odpowiedź, nadal nie rozumiem celu tego stringtypu w TypeScript, ponieważ pod koniec dnia , ('My String')['constructor'] === String...
mindplay.dk
2
Zazwyczaj dodajesz adnotację, jeśli nie inicjujesz zmiennej wartością.
Fenton
2
Dodałem odpowiedź, aby wyjaśnić, że „foo” vs nowy ciąg („foo”) nie jest nowym rozróżnieniem wprowadzonym przez TypeScript - nie sądzę, aby nazywanie jednego typu JS, a drugiego typu TS było pomocne.
Joe Lee-Moyet,
60

Te dwa typy są różne w JavaScript i TypeScript - TypeScript po prostu daje nam składnię do adnotacji i sprawdzania typów w miarę postępów.

Stringodnosi się do instancji obiektu, która ma String.prototypew swoim łańcuchu prototypów. Można dostać taki przypadek w różny sposób, na przykład new String('foo')a Object('foo'). Możesz przetestować wystąpienie Stringtypu z instanceofoperatorem, np myString instanceof String.

stringjest jednym z prymitywnych typów JavaScript, a stringwartości są tworzone przede wszystkim za pomocą literałów, np. 'foo'i "bar", oraz jako wynikowy typ różnych funkcji i operatorów. Możesz sprawdzić stringtyp za pomocą typeof myString === 'string'.

Zdecydowana większość czasu stringjest typem, którego powinieneś używać - prawie wszystkie interfejsy API, które pobierają lub zwracają ciągi, będą go używać. Wszystkie pierwotne typy JS zostaną zawinięte ( zapakowane w pudełka ) odpowiadającymi im typami obiektów podczas używania ich jako obiektów, np. Dostępu do właściwości lub metod wywoływania. Ponieważ Stringw bibliotece podstawowej TypeScript jest obecnie zadeklarowany jako interfejs, a nie klasa , typowanie strukturalne oznacza, że stringuważa się, że podtyp tego Stringjest pierwszym powodem, dla którego pierwszy wiersz przechodzi sprawdzanie typu kompilacji.

Joe Lee-Moyet
źródło
2

W JavaScript łańcuchy mogą być zarówno pierwotnymi typami łańcuchów, jak i obiektami łańcuchowymi. Poniższy kod pokazuje to rozróżnienie:

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

Twój błąd:

Wpisz „String” nie można przypisać do „string”. „ciąg” jest prymitywny, ale „ciąg” jest obiektem opakowującym. Jeśli to możliwe, preferuj użycie „łańcucha”.

Jest generowany przez kompilator TS, ponieważ próbowałeś przypisać typ stringdo typu obiektu łańcuchowego (utworzonego za pomocą newsłowa kluczowego). Kompilator mówi ci, że powinieneś używać tego typu stringtylko dla pierwotnych typów łańcuchów i nie możesz używać tego typu do opisywania typów obiektów łańcuchowych.

Willem van der Veen
źródło
1

TypeScript: Stringvsstring

Argument typu „String” nie może być przypisany do parametru typu „String”.

„ciąg” jest prymitywny, ale „ciąg” jest obiektem opakowującym.

Jeśli to możliwe, preferuj użycie „łańcucha”.

próbny

Obiekt ciągu

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

łańcuch prymitywny

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

wprowadź opis zdjęcia tutaj

xgqfrms
źródło