У Typescript, як перевірити, чи є рядок числовим


184

У Typescript це показує помилку, вказуючи, що isNaN приймає лише числові значення

isNaN('9BX46B6A')

і це повертає помилково, оскільки parseFloat('9BX46B6A')оцінює до9

isNaN(parseFloat('9BX46B6A'))

Я все ще можу працювати з помилкою, яка з’являється у Visual Studio, але я хотів би зробити це правильно.

В даний час я написав цю змінену функцію -

static isNaNModified = (inputStr: string) => {
    var numericRepr = parseFloat(inputStr);
    return isNaN(numericRepr) || numericRepr.toString().length != inputStr.length;
}

Відповіді:


338

Спосіб перетворення рядка в число є за допомогою Number, не parseFloat.

Number('1234') // 1234
Number('9BX9') // NaN

Ви також можете скористатися оператором unary plus, якщо вам подобається скорочення:

+'1234' // 1234
+'9BX9' // NaN

Будьте уважні, перевіряючи NaN (оператор ===і !==не працюйте так, як очікувалося NaN). Використання:

 isNaN(maybeNumber) // returns true if NaN, otherwise false

18
чи означає це, що робити це: якщо (isNaN (+ можливийNumberString)) є дійсним способом перевірки?
— Mathijs Segers

5
Чому б ви використовували Numberвище parseIntчи parseFloat? Number('')дає 0, а parseInt('')дає, NaNщо більше відповідає тому, що я очікую.
— Дідій

6
Як зазначено в первинному питанні , parseInt('9BX9')(і parseFloat('9BX9')) повернеться 9, не NaN. Якщо ви не хочете перетворення порожнього рядка в 0, спершу явно перевірте, чи є порожній рядок.
— C Snover

1
Якщо ви хочете перевірити це, використовуйте isNaN(Number(what_ever))замість Number(what_ever) === Nan.
— k0pernikus

3
@sauntimo Number- це не річ TypeScript, це вбудована функція конструктора EcmaScript, яка приймає значення і повертає примітив числа, коли викликається як функція, а не конструктор.
— C Snover

46

Оновлення 2

Цей метод більше не доступний у rxjs v6

Я вирішую це за допомогою оператора isNumeric з бібліотеки rxjs (імпортує rxjs / util / isNumeric

Оновлення

import { isNumeric } from 'rxjs/util/isNumeric';

. . .

var val = "5700";
if (isNumeric(val)){
   alert("it is number !");
}

5
Цей метод більше не доступний у rxjs v6.
— Логіка01



3

Я вибрав би існуюче і вже перевірене рішення. Наприклад, це від rxjs у typecript:

function isNumeric(val: any): val is number | string {
  // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  // subtraction forces infinities to NaN
  // adding 1 corrects loss of precision from parseFloat (#15100)
  return !isArray(val) && (val - parseFloat(val) + 1) >= 0;
}

rxjs / isNumeric.ts

Без функції rxjs isArray () та з спрощеними типізаціями:

function isNumeric(val: any): boolean {
  return !(val instanceof Array) && (val - parseFloat(val) + 1) >= 0;
}

Ви завжди повинні перевіряти такі функції у своїх випадках використання. Якщо у вас є спеціальні типи значень, ця функція може не бути вашим рішенням. Ви можете протестувати функцію тут.

Результати:

enum         : CardTypes.Debit   : true
decimal      : 10                : true
hexaDecimal  : 0xf10b            : true
binary       : 0b110100          : true
octal        : 0o410             : true
stringNumber : '10'              : true

string       : 'Hello'           : false
undefined    : undefined         : false
null         : null              : false
function     : () => {}          : false
array        : [80, 85, 75]      : false
turple       : ['Kunal', 2018]   : false
object       : {}                : false

Як бачите, ви повинні бути обережними, якщо ви використовуєте цю функцію із перерахунками.


1

Більшу частину часу значення, яке ми хочемо перевірити, - це рядок або число, тому ось функція, яку я використовую:

const isNumber = (n: string | number): boolean => 
    !isNaN(parseFloat(String(n))) && isFinite(Number(n));

Тести кодових ящиків .

const willBeTrue = [0.1, '1', '-1', 1, -1, 0, -0, '0', "-0", 2e2, 1e23, 1.1, -0.1, '0.1', '2e2', '1e23', '-0.1', ' 898', '080']

const willBeFalse = ['9BX46B6A', "+''", '', '-0,1', [], '123a', 'a', 'NaN', 1e10000, undefined, null, NaN, Infinity, () => {}]

1

Ви можете використовувати Number.isFinite()функцію:

Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false
Number.isFinite('0');       // false
Number.isFinite(null);      // false

Number.isFinite(0);         // true
Number.isFinite(2e64);      // true

Примітка. Існує значна різниця між глобальною функцією isFinite()та останньою Number.isFinite(). У випадку колишнього застосовується струнний примус - isFinite('0') === trueпоки що Number.isFinite('0') === false.

Також зауважте, що це не доступно в IE!


Але ... TS2345: Аргумент типу '' 1 '' не призначається параметру типу 'число'. Він повинен бути Number.isFinite (Number ('0'));
— Макгрі

0

Для повних чисел (не плаваючих) у Angular ви можете використовувати:

if (Number.isInteger(yourVariable)) { ... }


1
Number.isIntegerпросто повідомляє, якщо yourVariableце вже numberтип, це ціле число. Не працює зі струнами. Отже, Number.isInteger(Number(yourVariable))може зробити трюк.
— тарбол

-2

Чи може розбиття рядка як числа є проблемою виконання. Typescript не підтримує цей випадок використання, оскільки він орієнтований на безпеку часу компіляції (не час виконання).


11
Досить стурбованості, щоб позначити це як помилку, ніби припустити, що це неправильно.
— Джейн Панда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.