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)))