No texto datilografado, como verificar se uma seqüência de caracteres é numérica


184

No texto datilografado, isso mostra um erro dizendo que isNaN aceita apenas valores numéricos

isNaN('9BX46B6A')

e isso retorna falso porque parseFloat('9BX46B6A')avalia como9

isNaN(parseFloat('9BX46B6A'))

Ainda posso executar com o erro exibido no Visual Studio, mas gostaria de fazê-lo da maneira certa.

Atualmente, eu escrevi essa função modificada -

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

Respostas:


338

A maneira de converter uma string em um número é com Number, não parseFloat.

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

Você também pode usar o operador unary plus se desejar abreviar:

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

Tenha cuidado ao verificar o NaN (o operador ===e !==não funcione conforme o esperado NaN). Usar:

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

18
isso significa que fazer isso: se (isNaN (+ possibleNumberString)) é uma maneira válida de verificar?
Mathijs Segers

5
Por que você usaria Numberacima parseIntou parseFloat? Number('')dá 0 enquanto parseInt('')dá o NaNque está mais alinhado com o que eu espero.
Didii

6
Como mencionado na pergunta original , parseInt('9BX9')(e parseFloat('9BX9')) retornará 9, não NaN. Se você não deseja a conversão de uma sequência vazia em 0, verifique explicitamente primeiro a sequência vazia.
C # Snover #

1
Se você deseja verificar, use em isNaN(Number(what_ever))vez de Number(what_ever) === Nan.
K0pernikus

3
@sauntimo Numbernão é uma coisa do TypeScript, é uma função construtora interna do EcmaScript que aceita um valor e retorna um número primitivo quando chamado como uma função e não como um construtor.
C # Snover

46

Atualização 2

Este método não está mais disponível no rxjs v6

Estou resolvido-lo usando o isNumeric operador de rxjs biblioteca (importação rxjs / util / isNumeric

Atualizar

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

. . .

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

5
Este método não está mais disponível no rxjs v6.
Logic01

35
function isNumber(value: string | number): boolean
{
   return ((value != null) &&
           (value !== '') &&
           !isNaN(Number(value.toString())));
}


3

Eu escolheria uma solução existente e já testada. Por exemplo, isso de rxjs no texto datilografado:

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

Sem a função isxArray () e com tipificações simplificadas:

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

Você sempre deve testar essas funções com seus casos de uso. Se você possui tipos de valores especiais, essa função pode não ser a sua solução. Você pode testar a função aqui.

Os resultados são:

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

Como você pode ver, você deve ter cuidado se usar esta função com enumerações.


1

Na maioria das vezes, o valor que queremos verificar é string ou número, então aqui está a função que eu uso:

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

Testes de Codesandbox .

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

Você pode usar a Number.isFinite()função:

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

Nota: há uma diferença significativa entre a função global isFinite()e a última Number.isFinite(). No caso do primeiro, a coerção das cordas é realizada - portanto, isFinite('0') === trueenquanto Number.isFinite('0') === false.

Além disso, observe que isso não está disponível no IE!


Mas ... TS2345: O argumento do tipo '"1"' não é atribuível ao parâmetro do tipo 'número'. Ele precisa ser Number.isFinite (Number ('0'));
Mcgri 07/06

0

Para números completos (não flutuantes) no Angular, você pode usar:

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


1
Number.isIntegerapenas informa se yourVariable, que já é um numbertipo, é um número inteiro. Não funciona com strings. Então, Number.isInteger(Number(yourVariable))pode fazer o truque.
tarrball

-2

Se uma sequência pode ser analisada como um número é uma preocupação em tempo de execução. O Typecript não suporta esse caso de uso, pois está focado na segurança do tempo de compilação (não no tempo de execução).


11
É uma preocupação suficiente marcá-lo como um erro, como se sugerisse que não está correto.
Jane Panda
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.