Żeby zamienić string na liczbę w TypeScript, wywołaj Number(text). Wynik ma typ number i jest równy NaN, gdy tekst nie jest poprawną liczbą. Dla tekstu ze znakami na końcu, na przykład "42px", użyj parseInt(text, 10) albo parseFloat(text).
Wszystkie cztery konwersje zwracają typ number. TypeScript nie wie, czy tekst był poprawny: niepoprawny string też daje number, którego wartość to NaN.
Dlaczego trzeba konwertować
Pola formularzy, parametry URL, zmienne środowiskowe i zawartość plików przychodzą jako stringi. TypeScript nie pozwoli użyć takiej wartości tam, gdzie oczekiwana jest liczba:
index.ts(3,23): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
Arytmetyka z -, * i / na stringu to błąd. + jest dozwolony, ale łączy napisy, więc "3" + 10 to string "310". Dlatego konwersja musi być pierwsza: Number(quantity) * 10.
Asercja typu też nie pomoże. quantity as number zostaje odrzucone (TS2352), a wymuszenie przez as unknown as number tylko ucisza kompilator: w czasie wykonania wartość pozostaje stringiem.
Number, parseInt, parseFloat i jednoargumentowy plus
Cztery funkcje zgadzają się przy czystych danych i różnią się we wszystkim innym. Ta tabela to prawdziwy wynik każdej z nich w Node:
| Wejście | Number(s) | +s | parseInt(s, 10) | parseFloat(s) |
|---|---|---|---|---|
"42" | 42 | 42 | 42 | 42 |
"3.99" | 3.99 | 3.99 | 3 | 3.99 |
"42px" | NaN | NaN | 42 | 42 |
"" | 0 | 0 | NaN | NaN |
" 3 " | 3 | 3 | 3 | 3 |
"1e3" | 1000 | 1000 | 1 | 1000 |
"0x1F" | 31 | 31 | 0 | 0 |
"1,000" | NaN | NaN | 1 | 1 |
"12_000" | NaN | NaN | 12 | 12 |
"abc" | NaN | NaN | NaN | NaN |
Zasady stojące za tabelą:
Numberi jednoargumentowy+działają identycznie. Konwertują cały string po obcięciu białych znaków, rozumieją1e3i szesnastkowe0x, a jeśli coś zostanie, zwracająNaN. Pusty string albo string z samych białych znaków staje się0.parseIntiparseFloatczytają od początku i zatrzymują się na pierwszym znaku, którego nie potrafią użyć, więc"42px"i"1,000"dają częściowe liczby. Pusty string toNaN.parseIntodcina część ułamkową i nie rozumie wykładników:"1e3"zatrzymuje się nae.- Separatory liczbowe (
12_000) są poprawne w kodzie źródłowym, ale nie w stringach.
Number to ostrzejszy wybór do walidacji danych wejściowych. parseInt i parseFloat pasują do tekstu, który naprawdę zawiera jednostkę albo przyrostek, jak rozmiary w CSS.
Obsługa niepoprawnych danych: NaN
NaN ma typ number, więc kompilator nigdy przed nim nie ostrzeże. Sprawdź wynik samodzielnie, przez Number.isNaN albo Number.isFinite:
Zwracanie number | undefined sprawia, że porażka staje się częścią typu, więc każde wywołanie musi ją obsłużyć przed obliczeniami. Number.isFinite odrzuca też Infinity, które Number("Infinity") chętnie zwraca.
Unikaj globalnego isNaN(x): najpierw konwertuje argument, więc w JavaScript isNaN("abc") to true. Deklaracja w TypeScript przyjmuje tylko number, więc przekazanie stringa to błąd TS2345. To podpowiedź, żeby użyć Number.isNaN na już przekonwertowanej wartości.
String na liczbę całkowitą
Zawsze podawaj parseInt drugi argument, podstawę: 10 dla tekstu dziesiętnego. Jest opcjonalny, ale pokazuje intencję i ma znaczenie przy innych podstawach. Żeby dostać liczbę całkowitą ze stringa z częścią ułamkową, przekonwertuj go, a potem jawnie zaokrąglij.
parseInt oczekuje stringa: parseInt(12.7) to błąd kompilacji (TS2345). To przydatne, bo w JavaScript parseInt na liczbie najpierw zamienia ją na tekst i daje złe wyniki dla wartości takich jak 0.0000005 (zwraca 5). Dla liczb używaj Math.trunc. Dla liczb całkowitych większych niż Number.MAX_SAFE_INTEGER BigInt(text) parsuje pełną wartość (a przy niepoprawnym tekście rzuca SyntaxError, zamiast zwrócić NaN).
Number na string
Każde z String(n), n.toString() i `${n}` zamienia liczbę na jej najkrótszą postać tekstową. Metody formatujące dają większą kontrolę:
toFixed zaokrągla wartość binarną, a nie wpisaną liczbę dziesiętną, więc (1.005).toFixed(2) to "1.00": 1.005 jest przechowywane jako nieco mniej niż 1.005. Przy pieniądzach trzymaj kwoty jako całkowite grosze albo formatuj przez Intl.NumberFormat.
String(n) działa też na null i undefined (daje "null" i "undefined"), a n.toString() byłoby w trybie strict błędem kompilacji, bo wartości może brakować.
Ściąga
| Zadanie | Kod | Typ wyniku |
|---|---|---|
| String na liczbę, ściśle | Number(s) albo +s | number (może być NaN) |
| Liczba całkowita z początku tekstu | parseInt(s, 10) | number (może być NaN) |
| Liczba dziesiętna z początku tekstu | parseFloat(s) | number (może być NaN) |
| Sprawdzenie wyniku | Number.isFinite(n), Number.isNaN(n) | boolean |
| Duża liczba całkowita | BigInt(s) | bigint |
| Liczba na string | String(n), n.toString(), `${n}` | string |
| Stała liczba miejsc po przecinku | n.toFixed(2) | string |
| Inna podstawa | n.toString(16) | string |
| Separatory tysięcy | n.toLocaleString("en-US") | string |
Najczęściej zadawane pytania
Jak zamienić string na liczbę w TypeScript?
Użyj Number(text). Zwraca number: wartość dla poprawnego tekstu liczbowego, NaN dla każdego innego i 0 dla pustego stringa lub stringa z samych białych znaków. Użyj parseInt(text, 10) albo parseFloat(text), gdy tekst może mieć znaki na końcu, na przykład "42px".
Czy mogę rzutować string na liczbę przez as number?
as number?Nie. "42" as number to błąd kompilacji (TS2352), a nawet wymuszona przez unknown asercja zmienia tylko typ widziany przez kompilator: w czasie wykonania wartość to wciąż string "42". Przekonwertuj wartość przez Number(), parseInt() albo parseFloat().
Czym różni się Number() od parseInt() w TypeScript?
Number konwertuje cały string i zwraca NaN, jeśli którakolwiek część nie jest liczbą, więc Number("42px") to NaN. parseInt czyta cyfry od początku i zatrzymuje się na pierwszym znaku, który nie jest cyfrą, więc parseInt("42px", 10) to 42, a do tego odcina część ułamkową. Number("") to 0, a parseInt("") to NaN.
Jak sprawdzić, czy string jest poprawną liczbą?
Przekonwertuj go i sprawdź wynik: const n = Number(text); if (text.trim() !== "" && Number.isFinite(n)) { ... }. Sprawdzenie pustego stringa jest ważne, bo Number("") to 0. Używaj Number.isNaN, a nie globalnego isNaN, które TypeScript i tak przyjmuje tylko z argumentem typu number.
Jak zamienić liczbę na string w TypeScript?
String(n), n.toString() i template literal `${n}` dają ten sam wynik. Użyj n.toFixed(2) dla stałej liczby miejsc po przecinku, n.toString(16) dla innej podstawy i n.toLocaleString("en-US") dla separatorów tysięcy.