1

Here are the validations which I want to apply:

  1. The string should contain any character between 0 to 9.
  2. It should not contain any alphabetical character.
  3. It can contain at most one '-' (minus operator) which will signify a negative number such as "-12".
  4. It can also contain at most one '.' to cover the case of floating numbers such as "12.2"

Now I have tried various combinations but still I am unsuccessful to create such a condition in Typescript. Here's what I tried:

  • using regex /^[0-9.{0,1}-{0,1}]/.test(mystring)

Unfortunately, this didn't work for me. Can anyone please help me to get the desired solution?

jcalz
  • 264,269
  • 27
  • 359
  • 360
KhiladiBhaiyya
  • 633
  • 1
  • 14
  • 43
  • 2
    Typescript isn't a runtime language. – Kenneth K. Jul 11 '18 at 13:59
  • @KennethK. I checked my solution with the help of console.log(). – KhiladiBhaiyya Jul 11 '18 at 14:01
  • 1
    I'm saying that Typescript itself isn't a programming language. Rather, it's (effectively) an enhancement to Javascript that provides for compile-time typing of your Javascript data. So I don't see what Typescript itself has to do with this issue. You have a Javascript problem, and that you should be able to debug with `console`. – Kenneth K. Jul 11 '18 at 14:03
  • 1
    TypeScript isn't a programming language? Now I'm sad. – jcalz Jul 11 '18 at 14:04
  • 2
    @jcalz I was afraid I'd catch flak for that statement. I'm not sure how to say what I mean :) – Kenneth K. Jul 11 '18 at 14:05
  • @DG4 what is your actual use case? Do you want to verify everything that JavaScript interprets as number (like `1.234e+30`) or just the particular restrictions you mention? – jcalz Jul 11 '18 at 14:06
  • @KennethK. TypeScript is a preprocessor language that provides strict typing via static analysis during compilation into JavaScript. – Patrick Roberts Jul 11 '18 at 14:07
  • why not `isNaN(parseFloat('-12.2') ? 'Invalid' : 'Valid';` ? – AdityaParab Jul 11 '18 at 14:09
  • 1
    Is there any check that `Number(val)` that's missing? @AdityaParab parseFloat will accept `12.3xyz`.. – Keith Jul 11 '18 at 14:11
  • @Keith yep.. my bad... I also realize that it will also accept `12.....3` and give you 12 – AdityaParab Jul 11 '18 at 14:13

3 Answers3

8

In TypeScript, use the following function which can accept any value:

const isFixed = (o: any) => {
  const s = String(o)
  return !isNaN(+s) && isFinite(+s) && (typeof o === 'number' || !/e/i.test(s))
}

Or if you're only checking strings:

const isFixedString = (s: string) => !isNaN(+s) && isFinite(+s) && !/e/i.test(s)

Note that the explicit String() casting in the first function is to avoid calling the value's toString() or valueOf() or [Symbol.toPrimitive]() more than once and risk checking conflicting values of auto-updating types like { n: 0, valueOf: () => n++ }.

The casts using the unary + operator in both definitions are specifically for the parameter types to be compatible with the global definitions in TypeScript for isNaN() and isFinite(), which expect a number argument for some reason even though JavaScript can handle any type. Otherwise these casts can be removed without any change to the result.

Explanation

Just using !isNaN(mystring), you will check whether casting the string with Number() will result in NaN:

let arr = ['5', '-5', '.5', '5.', '0', '5e0', '5E0', 'Infinity', '-Infinity', '5a', 'n', '--5'];

arr.forEach(str => console.log(str, !isNaN(str)))

It should be noted that this approach also accepts scientific notation and Infinity, which needs to be handled separately with isFinite(mystring) && !/e/i.test(mystring):

let arr = ['5', '-5', '.5', '5.', '0', '5e0', '5E0', 'Infinity', '-Infinity', '5a', 'n', '--5'];

arr.forEach(str => console.log(str, !isNaN(str) && isFinite(str) && !/e/i.test(str)))
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
2

As explained in the comments above, parseFloat will not satisfy all your requirements. And I don't like Reg Ex approach for this kinda things.

The simplest way for you would be to coerce string into a number using unary +

const stringTransformedToNumber = +"-12.3";

const isInvalid = isNaN(stringTransformedToNumber);

console.log(isInvalid ? 'Invalid' : 'Valid');

Even better way is to just use isNaN:

const isInvalid = isNaN("-12.3");

console.log(isInvalid ? 'Invalid' : 'Valid');
AdityaParab
  • 7,024
  • 3
  • 27
  • 40
-2

Try sth like this:

/^\-?(([1-9]\d*)|0)(\.\d+)?$/

  • `5.` and `.5` should be a valid numbers, and they would both fail this check. Easier to just `const isNumber = n => !isNaN(n)` – Patrick Roberts Jul 11 '18 at 14:09
  • [*Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.* - Jamie Zawinski](http://regex.info/blog/2006-09-15/247) –  Jul 11 '18 at 14:26