What is is-what?
The is-what npm package provides utility functions to check the type of a given value. It helps in determining whether a value is an object, array, function, string, number, etc. This can be particularly useful in type-checking scenarios and ensuring that values conform to expected types.
What are is-what's main functionalities?
isObject
The isObject function checks if a given value is a plain object. It returns true for plain objects and false for arrays and other types.
const { isObject } = require('is-what');
console.log(isObject({})); // true
console.log(isObject([])); // false
isArray
The isArray function checks if a given value is an array. It returns true for arrays and false for other types.
const { isArray } = require('is-what');
console.log(isArray([])); // true
console.log(isArray({})); // false
isFunction
The isFunction function checks if a given value is a function. It returns true for functions and false for other types.
const { isFunction } = require('is-what');
console.log(isFunction(function() {})); // true
console.log(isFunction({})); // false
isString
The isString function checks if a given value is a string. It returns true for strings and false for other types.
const { isString } = require('is-what');
console.log(isString('hello')); // true
console.log(isString(123)); // false
isNumber
The isNumber function checks if a given value is a number. It returns true for numbers and false for other types.
const { isNumber } = require('is-what');
console.log(isNumber(123)); // true
console.log(isNumber('123')); // false
Other packages similar to is-what
lodash
Lodash is a popular utility library that provides a wide range of functions for manipulating arrays, objects, and other types. It includes type-checking functions similar to is-what, such as _.isObject, _.isArray, _.isFunction, _.isString, and _.isNumber. Lodash offers more comprehensive functionality beyond type-checking.
underscore
Underscore is another utility library that provides functional programming helpers for working with arrays, objects, and other types. It includes type-checking functions like _.isObject, _.isArray, _.isFunction, _.isString, and _.isNumber. Underscore is similar to Lodash but with a smaller footprint and fewer features.
type-detect
Type-detect is a simple library for detecting the type of a given value. It provides functions like typeDetect(value) which returns a string representing the type of the value. While it offers similar functionality to is-what, it focuses on returning type names rather than boolean checks.
is What? 🙉
Very simple & small JS type check functions. It's fully TypeScript supported!
npm i is-what
Or for deno available at: "deno.land/x/is_what"
Motivation
I built is-what because the existing solutions were all too complex or too poorly built.
I was looking for:
- A simple way to check any kind of type (including non-primitives)
- Be able to check if an object is a plain object
{}
or a special object (like a class instance) ‼️ - Let TypeScript automatically know what type a value is when checking
And that's exactly what is-what
is! (what a great wordplay 😃)
Usage
is-what is really easy to use, and most functions work just like you'd expect.
import { isString, isDate, isPlainObject } from 'is-what'
- First I'll go over the simple functions available. Only
isNumber
and isDate
have special treatment. - After that I'll talk about working with Objects (plain objects vs class instances etc.).
- Lastly I'll talk about TypeScript implementation
Simple type check functions
isBoolean(true)
isBoolean(false)
isUndefined(undefined)
isNull(null)
isString('')
isEmptyString('')
isFullString('')
isNumber(0)
isNumber('0')
isNumber(NaN)
isPositiveNumber(1)
isNegativeNumber(-1)
isArray([])
isEmptyArray([])
isFullArray([1])
isPlainObject({})
isEmptyObject({})
isFullObject({ a: 1 })
isFunction(function () {})
isFunction(() => {})
isDate(new Date())
isDate(new Date('invalid date'))
isMap(new Map())
isSet(new Set())
isWeakMap(new WeakMap())
isWeakSet(new WeakSet())
isRegExp(/\s/gi)
isSymbol(Symbol())
isBlob(new Blob())
isFile(new File([''], '', { type: 'text/html' }))
isError(new Error(''))
isPromise(new Promise((resolve) => {}))
isPrimitive('')
Let's talk about NaN
isNaN
is a built-in JS Function but it really makes no sense:
typeof NaN === 'number'
isNaN('1')
isNaN('one')
With is-what the way we treat NaN makes a little bit more sense:
import { isNumber, isNaNValue } from 'is-what'
isNumber(NaN)
isNaNValue('1')
isNaNValue('one')
isNaNValue(NaN)
isPlainObject vs isAnyObject
Checking for a JavaScript object can be really difficult. In JavaScript you can create classes that will behave just like JavaScript objects but might have completely different prototypes. With is-what I went for this classification:
isPlainObject
will only return true
on plain JavaScript objects and not on classes or othersisAnyObject
will be more loose and return true
on regular objects, classes, etc.
const plainObject = { hello: 'I am a good old object.' }
class SpecialObject {
constructor(somethingSpecial) {
this.speciality = somethingSpecial
}
}
const specialObject = new SpecialObject('I am a special object! I am a class instance!!!')
isPlainObject(plainObject)
isAnyObject(plainObject)
getType(plainObject)
isPlainObject(specialObject)
isAnyObject(specialObject)
getType(specialObject)
Please note that isPlainObject
will only return true
for normal plain JavaScript objects.
Getting and checking for specific types
You can check for specific types with getType
and isType
:
import { getType, isType } from 'is-what'
getType('')
isType('', String)
TypeScript
is-what makes TypeScript know the type during if statements. This means that a check returns the type of the payload for TypeScript users.
function isNumber(payload: any): payload is number {
}
function fn(payload: string | number): number {
if (isNumber(payload)) {
return payload
}
return 0
}
isPlainObject
and isAnyObject
with TypeScript will declare the payload to be an object type with any props:
function isPlainObject(payload: any): payload is { [key: string]: any }
function isAnyObject(payload: any): payload is { [key: string]: any }
if (isPlainObject(payload) && payload.id) return payload.id
isObjectLike
If you want more control over what kind of interface/type is casted when checking for objects.
To cast to a specific type while checking for isAnyObject
, can use isObjectLike<T>
:
import { isObjectLike } from 'is-what'
const payload = { name: 'Mesqueeb' }
if (isAnyObject(payload)) {
}
if (isObjectLike<{ name: string }>(payload)) {
}
Please note: this library will not actually check the shape of the object, you need to do that yourself.
isObjectLike<T>
works like this under the hood:
function isObjectLike<T extends object>(payload: any): payload is T {
return isAnyObject(payload)
}
Meet the family
Source code
It's litterally just these functions:
function getType(payload) {
return Object.prototype.toString.call(payload).slice(8, -1)
}
function isUndefined(payload) {
return getType(payload) === 'Undefined'
}
function isString(payload) {
return getType(payload) === 'String'
}
function isAnyObject(payload) {
return getType(payload) === 'Object'
}
See the full source code here.