В 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

Вы также можете использовать унарный оператор плюс, если вам нравится сокращение:

+'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что больше соответствует тому, что я ожидаю.
Didii

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, которая принимает значение и возвращает числовой примитив при вызове как функции, а не конструктора.
С 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.
Logic01



3

Я бы выбрал существующее и уже опробованное решение. Например, это из rxjs в машинописи:

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

Для полных чисел (non-float) в Angular вы можете использовать:

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


1
Number.isIntegerпросто говорит вам, если yourVariable, который уже является numberтипом, является целым числом. Не работает со строками. Таким образом, Number.isInteger(Number(yourVariable))может сделать свое дело.
tarrball

-2

Возможность анализа строки как числа - вопрос времени выполнения. Typescript не поддерживает этот вариант использования, так как он ориентирован на безопасность во время компиляции (не во время выполнения).


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