{"id":13624498,"url":"https://github.com/mesqueeb/is-what","last_synced_at":"2025-05-14T14:08:09.276Z","repository":{"id":32971392,"uuid":"137840728","full_name":"mesqueeb/is-what","owner":"mesqueeb","description":"JS type check (TypeScript supported) functions like `isPlainObject() isArray()` etc. A simple \u0026 small integration.","archived":false,"fork":false,"pushed_at":"2025-04-30T19:14:35.000Z","size":1444,"stargazers_count":195,"open_issues_count":11,"forks_count":20,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-03T02:51:34.335Z","etag":null,"topics":["check-type","class-identifier","class-instance","define-type","get-type","is-object","is-plain-obj","is-plain-object","javascript","javascript-type","plain-object","plain-objects","primitive-types","type-check","type-checker","type-checking","typechecker","typescript","what-type"],"latest_commit_sha":null,"homepage":"https://mesqueeb.github.io/is-what/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mesqueeb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"mesqueeb","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2018-06-19T04:41:06.000Z","updated_at":"2025-04-18T22:12:09.000Z","dependencies_parsed_at":"2023-02-18T03:35:15.465Z","dependency_job_id":"bda7b9dd-ae0f-4f78-a008-a5e47d81fc13","html_url":"https://github.com/mesqueeb/is-what","commit_stats":{"total_commits":208,"total_committers":13,"mean_commits":16.0,"dds":0.5432692307692308,"last_synced_commit":"58d494a5a1820f64adb24049503c3892c69edf58"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mesqueeb%2Fis-what","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mesqueeb%2Fis-what/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mesqueeb%2Fis-what/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mesqueeb%2Fis-what/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mesqueeb","download_url":"https://codeload.github.com/mesqueeb/is-what/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254047118,"owners_count":22005725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["check-type","class-identifier","class-instance","define-type","get-type","is-object","is-plain-obj","is-plain-object","javascript","javascript-type","plain-object","plain-objects","primitive-types","type-check","type-checker","type-checking","typechecker","typescript","what-type"],"created_at":"2024-08-01T21:01:43.193Z","updated_at":"2025-05-14T14:08:09.256Z","avatar_url":"https://github.com/mesqueeb.png","language":"TypeScript","funding_links":["https://github.com/sponsors/mesqueeb"],"categories":["javascript","typescript"],"sub_categories":[],"readme":"# is What? 🙉\n\n\u003ca href=\"https://www.npmjs.com/package/is-what\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/is-what.svg\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/is-what\"\u003e\u003cimg src=\"https://img.shields.io/npm/dw/is-what.svg\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n\nVery simple \u0026 small JS type check functions. It's fully TypeScript supported!\n\n```\nnpm i is-what\n```\n\nOr for deno available at: `\"deno.land/x/is_what\"`\n\n\u003e Also check out [is-where 🙈](https://github.com/mesqueeb/is-where)\n\n## Motivation\n\nI built is-what because the existing solutions were all too complex or too poorly built.\n\nI was looking for:\n\n- A simple way to check any kind of type (including non-primitives)\n- Be able to check if an object is a plain object `{}` or a special object (like a class instance) ‼️\n- Let TypeScript automatically know what type a value is when checking\n\nAnd that's exactly what `is-what` is! (what a great wordplay 😃)\n\n## Usage\n\nis-what is really easy to use, and most functions work just like you'd expect.\n\n```js\n// import functions you want to use like so:\nimport { isString, isDate, isPlainObject } from 'is-what'\n```\n\n1. First I'll go over the simple functions available. Only `isNumber` and `isDate` have special treatment.\n2. After that I'll talk about working with Objects (plain objects vs class instances etc.).\n3. Lastly I'll talk about TypeScript implementation\n\n### Simple type check functions\n\n```js\n// basics\nisBoolean(true) // true\nisBoolean(false) // true\nisUndefined(undefined) // true\nisNull(null) // true\n\n// strings\nisString('') // true\nisEmptyString('') // true\nisFullString('') // false\nisHexDecimal('60adf084f0fbdcab42de841e') // true\nisHexDecimal('60adf084f0fbdcab42de841e', 24) // check specific length of 24 (eg. MongoDB ObjectId)\n\n// numbers\nisNumber(0) // true\nisNumber('0') // false\nisNumber(NaN) // false *\nisPositiveNumber(1) // true\nisNegativeNumber(-1) // true\n// * see below for special NaN use cases!\n\n// arrays\nisArray([]) // true\nisEmptyArray([]) // true\nisFullArray([1]) // true\n\n// objects\nisPlainObject({}) // true *\nisEmptyObject({}) // true\nisFullObject({ a: 1 }) // true\n// * see below for special object (\u0026 class instance) use cases!\n\n// functions\nisFunction(function () {}) // true\nisFunction(() =\u003e {}) // true\n\n// dates\nisDate(new Date()) // true\nisDate(new Date('invalid date')) // false\n\n// maps \u0026 sets\nisMap(new Map()) // true\nisSet(new Set()) // true\nisWeakMap(new WeakMap()) // true\nisWeakSet(new WeakSet()) // true\n\n// others\nisRegExp(/\\s/gi) // true\nisSymbol(Symbol()) // true\nisBlob(new Blob()) // true\nisFile(new File([''], '', { type: 'text/html' })) // true\nisError(new Error('')) // true\nisPromise(new Promise((resolve) =\u003e {})) // true\n\n// primitives\nisPrimitive('') // true\n//     true for any of: boolean, null, undefined, number, string, symbol\n\n// iterables\nisIterable([1, 2, 3]) // true\nisIterable('hello') // true\nisIterable(new Map()) // true\nisIterable(new Set()) // true\nisIterable(function* generator() {\n  yield 1\n}) // true\n```\n\n### Let's talk about NaN\n\n`isNaN` is a built-in JS Function but it really makes no sense:\n\n```js\n// 1)\ntypeof NaN === 'number' // true\n// 🤔 (\"not a number\" is a \"number\"...)\n\n// 2)\nisNaN('1') // false\n// 🤔 the string '1' is not-\"not a number\"... so it's a number??\n\n// 3)\nisNaN('one') // true\n// 🤔 'one' is NaN but `NaN === 'one'` is false...\n```\n\nWith is-what the way we treat NaN makes a little bit more sense:\n\n```js\nimport { isNumber, isNaNValue } from 'is-what'\n\n// 1)\nisNumber(NaN) // false!\n// let's not treat NaN as a number\n\n// 2)\nisNaNValue('1') // false\n// if it's not NaN, it's not NaN!!\n\n// 3)\nisNaNValue('one') // false\n// if it's not NaN, it's not NaN!!\n\nisNaNValue(NaN) // true\n```\n\n### isPlainObject vs isAnyObject\n\nChecking 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:\n\n- `isPlainObject` will only return `true` on plain JavaScript objects and not on classes or others\n- `isAnyObject` will be more loose and return `true` on regular objects, classes, etc.\n\n```js\n// define a plain object\nconst plainObject = { hello: 'I am a good old object.' }\n\n// define a special object\nclass SpecialObject {\n  constructor(somethingSpecial) {\n    this.speciality = somethingSpecial\n  }\n}\nconst specialObject = new SpecialObject('I am a special object! I am a class instance!!!')\n\n// check the plain object\nisPlainObject(plainObject) // returns true\nisAnyObject(plainObject) // returns true\ngetType(plainObject) // returns 'Object'\n\n// check the special object\nisPlainObject(specialObject) // returns false !!!!!!!!!\nisAnyObject(specialObject) // returns true\ngetType(specialObject) // returns 'Object'\n```\n\n\u003e Please note that `isPlainObject` will only return `true` for normal plain JavaScript objects.\n\n### Getting and checking for specific types\n\nYou can check for specific types with `getType` and `isType`:\n\n```js\nimport { getType, isType } from 'is-what'\n\ngetType('') // returns 'String'\n// pass a Type as second param:\nisType('', String) // returns true\n```\n\nIf you just want to make sure your object _inherits_ from a particular class or\n`toStringTag` value, you can use `isInstanceOf()` like this:\n\n```js\nimport { isInstanceOf } from 'is-what'\n\nisInstanceOf(new XMLHttpRequest(), 'EventTarget')\n// returns true\nisInstanceOf(globalThis, ReadableStream)\n// returns false\n```\n\n## TypeScript\n\nis-what makes TypeScript know the type during if statements. This means that a check returns the type of the payload for TypeScript users.\n\n```ts\nfunction isNumber(payload: unknown): payload is number {\n  // return boolean\n}\n// As you can see above, all functions return a boolean for JavaScript, but pass the payload type to TypeScript.\n\n// usage example:\nfunction fn(payload: string | number): number {\n  if (isNumber(payload)) {\n    // ↑ TypeScript already knows payload is a number here!\n    return payload\n  }\n  return 0\n}\n```\n\n`isPlainObject` and `isAnyObject` with TypeScript will declare the payload to be an object type with any props:\n\n```ts\nfunction isPlainObject(payload: unknown): payload is { [key: string]: unknown }\nfunction isAnyObject(payload: unknown): payload is { [key: string]: unknown }\n// The reason to return `{[key: string]: unknown}` is to be able to do\nif (isPlainObject(payload) \u0026\u0026 payload.id) return payload.id\n// if isPlainObject() would return `payload is object` then it would give an error at `payload.id`\n```\n\n### isObjectLike\n\nIf you want more control over what kind of interface/type is casted when checking for objects.\n\nTo cast to a specific type while checking for `isAnyObject`, can use `isObjectLike\u003cT\u003e`:\n\n```ts\nimport { isObjectLike } from 'is-what'\n\nconst payload = { name: 'Mesqueeb' } // current type: `{ name: string }`\n\n// Without casting:\nif (isAnyObject(payload)) {\n  // in here `payload` is casted to: `Record\u003cstring | number | symbol, unknown\u003e`\n  // WE LOOSE THE TYPE!\n}\n\n// With casting:\n// you can pass a specific type for TS that will be casted when the function returns\nif (isObjectLike\u003c{ name: string }\u003e(payload)) {\n  // in here `payload` is casted to: `{ name: string }`\n}\n```\n\nPlease note: this library will not actually check the shape of the object, you need to do that yourself.\n\n`isObjectLike\u003cT\u003e` works like this under the hood:\n\n```ts\nfunction isObjectLike\u003cT extends object\u003e(payload: unknown): payload is T {\n  return isAnyObject(payload)\n}\n```\n\n## Meet the family (more tiny utils with TS support)\n\n- [is-what 🙉](https://github.com/mesqueeb/is-what)\n- [is-where 🙈](https://github.com/mesqueeb/is-where)\n- [merge-anything 🥡](https://github.com/mesqueeb/merge-anything)\n- [check-anything 👁](https://github.com/mesqueeb/check-anything)\n- [remove-anything ✂️](https://github.com/mesqueeb/remove-anything)\n- [getorset-anything 🐊](https://github.com/mesqueeb/getorset-anything)\n- [map-anything 🗺](https://github.com/mesqueeb/map-anything)\n- [filter-anything ⚔️](https://github.com/mesqueeb/filter-anything)\n- [copy-anything 🎭](https://github.com/mesqueeb/copy-anything)\n- [case-anything 🐫](https://github.com/mesqueeb/case-anything)\n- [flatten-anything 🏏](https://github.com/mesqueeb/flatten-anything)\n- [nestify-anything 🧅](https://github.com/mesqueeb/nestify-anything)\n\n## Source code\n\nIt's litterally just these functions:\n\n```js\nfunction getType(payload) {\n  return Object.prototype.toString.call(payload).slice(8, -1)\n}\nfunction isUndefined(payload) {\n  return getType(payload) === 'Undefined'\n}\nfunction isString(payload) {\n  return getType(payload) === 'String'\n}\nfunction isAnyObject(payload) {\n  return getType(payload) === 'Object'\n}\n// etc...\n```\n\nSee the full source code [here](https://github.com/mesqueeb/is-what/blob/main/src/index.ts).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmesqueeb%2Fis-what","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmesqueeb%2Fis-what","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmesqueeb%2Fis-what/lists"}