-(Edited)This question does not apply to only Numbers, but about all types in general. I am using something like:
exampleFunction1(a,b){
if(
Object.prototype.toString.call(a) === "[object Number]" &&
Object.prototype.toString.call(b) === "[object Number]"
){
return a+b;
}else{
console.log('%cType Error : exampleFunction1(<Number>)','color:#00FF66;')
}
}
exampleFunction2(type,length,format) {
if(
Object.prototype.toString.call(type) === "[object String]" &&
Object.prototype.toString.call(length) === "[object Number]" &&
(Object.prototype.toString.call(format) === "[object String]" || Object.prototype.toString.call(format) === "[object Undefined]" )
){
}else{
console.log("%cType Error : exampleFunction2(<String>,<Number>,<String>)","color:#00FF66;")
}
}
in almost all of my functions to strict check its input type before starting to write my actual code. And its mostly on functions that i'll share amongst my team and on my own library which other people will try to use. Is this considered as a good practice or it's unnecessary ?
-
1It's far better to use facebook's flow or microsoft's typescript.Marco– Marco2020年05月26日 00:43:19 +00:00Commented May 26, 2020 at 0:43
-
@marco-a the problem of typescript is that it does not check during run time and it breaks some of the es6 syntax, which makes it more time consuming to fix it.Tsubaki Cerceis– Tsubaki Cerceis2020年05月26日 00:45:17 +00:00Commented May 26, 2020 at 0:45
-
typescript is compiled to javascript. all checks will be done during run time; though they will be implicit and hidden awayrichytong– richytong2020年05月26日 01:08:55 +00:00Commented May 26, 2020 at 1:08
-
@richytong You sure ? According to this post's answer stackoverflow.com/a/44078574/10822847 typescript does not check type during run time.Tsubaki Cerceis– Tsubaki Cerceis2020年05月26日 01:12:43 +00:00Commented May 26, 2020 at 1:12
-
okay, you got me. thanks for showing me thatrichytong– richytong2020年05月26日 01:15:37 +00:00Commented May 26, 2020 at 1:15
3 Answers 3
You won't find one right answer, but you can find strong opinions. My opinion is: it varies. Here are some typechecks from my library
const isDefined = x => x !== undefined && x !== null
const isUndefined = x => x === undefined
const isNull = x => x === null
const isIterable = x => isDefined(x) && isDefined(x[Symbol.iterator])
const isAsyncIterable = x => isDefined(x) && isDefined(x[Symbol.asyncIterator])
const isReadable = x => x && typeof x.read === 'function'
const isWritable = x => x && typeof x.write === 'function'
const isFunction = x => typeof x === 'function'
const isArray = Array.isArray
const numberTypedArrays = new Set([
'Uint8ClampedArray',
'Uint8Array', 'Int8Array',
'Uint16Array', 'Int16Array',
'Uint32Array', 'Int32Array',
'Float32Array', 'Float64Array',
])
const isNumberTypedArray = x => x && x.constructor && (
numberTypedArrays.has(x.constructor.name)
)
const bigIntTypedArrays = new Set([
'BigUint64Array', 'BigInt64Array',
])
const isBigIntTypedArray = x => x && x.constructor && (
bigIntTypedArrays.has(x.constructor.name)
)
const isNumber = x => typeof x === 'number'
const isBigInt = x => typeof x === 'bigint'
const isString = x => typeof x === 'string'
const isPromise = x => x && typeof x.then === 'function'
const is = fn => x => x && x.constructor === fn
const isObject = is(Object) // checks directly for Object, isObject([]) === false
If you're looking for a quick way to just check the type given the constructor function, I recommend copy and pasting is and using it so
const is = fn => x => x && x.constructor === fn
exampleFunction1(a,b){
if(is(Number)(a) && is(Number)(b)){
return a+b;
}else{
console.log('%cType Error : exampleFunction1(<Number>)','color:#00FF66;')
}
}
it's less to type.
5 Comments
TypedArray which is hidden from the global namespace. I wanted to do an easy type check for Uint8Array, Int8Array, ..., Float64Array as a group, so that's how I arrived at isNumberTypedArray. I also ran into a bunch of one off cases like isDefined where I want to conveniently check for undefined and null. So i guess that's where all the variation came from for me.isReadable just checks for the function read. this is duck typing You should use isNaN method to check is number or not as
addNumbers(a,b){
if(
!isNaN(a) &&
!isNaN(b)
){
return a+b;
}else{
console.log('%cType Error : findUniqueInArray(<Array>)','color:#00FF66;')
}
}
3 Comments
isNaN() performs soft type check, so for example isNaN(true) is false.Number.IsNaN if you want check for input typeNumber.isNaN() on the other hand returns true just for the true NaN value. There's no magic behind it.Relying on toString() doesn't seem like the safest choice, as any object can implement its own toString().
I'd go with Number.isFinite():
if (Number.isFinite(a) && Number.isFinite(b)) {
If you just want to check the type, there's a typeof operator:
typeof 1 // "number"
typeof 'a' // "string"
typeof {} // "object"
As for the toString(), libraries often implement their own toString() to help you debug. Here's how it's done with classes:
class Foo {
toString() {
return 'I am mr. Foo';
}
}
const bar = new Foo();
bar.toString() // "I am mr. Foo"
10 Comments
Object.prototype.toString.call(obj) never calls obj.toString so that is not an issue.