{"id":13455175,"url":"https://github.com/sindresorhus/is","last_synced_at":"2025-12-27T16:09:25.899Z","repository":{"id":37271230,"uuid":"104379939","full_name":"sindresorhus/is","owner":"sindresorhus","description":"Type check values","archived":false,"fork":false,"pushed_at":"2024-09-06T15:55:32.000Z","size":1202,"stargazers_count":1713,"open_issues_count":9,"forks_count":116,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-05-08T08:04:49.216Z","etag":null,"topics":["assertions","is","node-module","npm-package","type-check","type-detection","typescript"],"latest_commit_sha":null,"homepage":"","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/sindresorhus.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":".github/security.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"sindresorhus","open_collective":"sindresorhus","buy_me_a_coffee":"sindresorhus","custom":"https://sindresorhus.com/donate"}},"created_at":"2017-09-21T17:46:08.000Z","updated_at":"2025-05-02T19:30:14.000Z","dependencies_parsed_at":"2024-01-13T10:13:48.170Z","dependency_job_id":"cd937b99-1d80-4868-a982-9780ddf262eb","html_url":"https://github.com/sindresorhus/is","commit_stats":{"total_commits":233,"total_committers":55,"mean_commits":4.236363636363636,"dds":"0.40772532188841204","last_synced_commit":"e0976457e04ba5df210ca0c976844b580b62f741"},"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sindresorhus","download_url":"https://codeload.github.com/sindresorhus/is/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253251187,"owners_count":21878434,"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":["assertions","is","node-module","npm-package","type-check","type-detection","typescript"],"created_at":"2024-07-31T08:01:02.081Z","updated_at":"2025-12-27T16:09:25.893Z","avatar_url":"https://github.com/sindresorhus.png","language":"TypeScript","readme":"# is\n\n\u003e Type check values\n\nFor example, `is.string('🦄') //=\u003e true`\n\n\u003cimg src=\"header.gif\" width=\"182\" align=\"right\"\u003e\n\n## Highlights\n\n- Written in TypeScript\n- [Extensive use of type guards](#type-guards)\n- [Supports type assertions](#type-assertions)\n- [Aware of generic type parameters](#generic-type-parameters) (use with caution)\n- Actively maintained\n- ![Millions of downloads per week](https://img.shields.io/npm/dw/@sindresorhus/is)\n\n## Install\n\n```sh\nnpm install @sindresorhus/is\n```\n\n## Usage\n\n```js\nimport is from '@sindresorhus/is';\n\nis('🦄');\n//=\u003e 'string'\n\nis(new Map());\n//=\u003e 'Map'\n\nis.number(6);\n//=\u003e true\n```\n\n[Assertions](#type-assertions) perform the same type checks, but throw an error if the type does not match.\n\n```js\nimport {assert} from '@sindresorhus/is';\n\nassert.string(2);\n//=\u003e Error: Expected value which is `string`, received value of type `number`.\n```\n\nAssertions (except `assertAll` and `assertAny`) also support an optional custom error message.\n\n```js\nimport {assert} from '@sindresorhus/is';\n\nassert.nonEmptyString(process.env.API_URL, 'The API_URL environment variable is required.');\n//=\u003e Error: The API_URL environment variable is required.\n```\n\nAnd with TypeScript:\n\n```ts\nimport {assert} from '@sindresorhus/is';\n\nassert.string(foo);\n// `foo` is now typed as a `string`.\n```\n\n### Named exports\n\nNamed exports allow tooling to perform tree-shaking, potentially reducing bundle size by including only code from the methods that are used.\n\nEvery method listed below is available as a named export. Each method is prefixed by either `is` or `assert` depending on usage.\n\nFor example:\n\n```js\nimport {assertNull, isUndefined} from '@sindresorhus/is';\n```\n\n## API\n\n### is(value)\n\nReturns the type of `value`.\n\nPrimitives are lowercase and object types are camelcase.\n\nExample:\n\n- `'undefined'`\n- `'null'`\n- `'string'`\n- `'symbol'`\n- `'Array'`\n- `'Function'`\n- `'Object'`\n\nThis method is also exported as `detect`. You can import it like this:\n\n```js\nimport {detect} from '@sindresorhus/is';\n```\n\nNote: It will throw an error if you try to feed it object-wrapped primitives, as that's a bad practice. For example `new String('foo')`.\n\n### is.{method}\n\nAll the below methods accept a value and return a boolean for whether the value is of the desired type.\n\n#### Primitives\n\n##### .undefined(value)\n##### .null(value)\n\n##### .string(value)\n##### .number(value)\n\nNote: `is.number(NaN)` returns `false`. This intentionally deviates from `typeof` behavior to increase user-friendliness of `is` type checks.\n\n##### .boolean(value)\n##### .symbol(value)\n##### .bigint(value)\n\n#### Built-in types\n\n##### .array(value, assertion?)\n\nReturns true if `value` is an array and all of its items match the assertion (if provided).\n\n```js\nis.array(value); // Validate `value` is an array.\nis.array(value, is.number); // Validate `value` is an array and all of its items are numbers.\n```\n\n##### .function(value)\n\n##### .buffer(value)\n\n\u003e [!NOTE]\n\u003e [Prefer using `Uint8Array` instead of `Buffer`.](https://sindresorhus.com/blog/goodbye-nodejs-buffer)\n\n##### .blob(value)\n##### .object(value)\n\nKeep in mind that [functions are objects too](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions).\n\n##### .numericString(value)\n\nReturns `true` for a string that represents a number satisfying `is.number`, for example, `'42'` and `'-8.3'`.\n\nNote: `'NaN'` returns `false`, but `'Infinity'` and `'-Infinity'` return `true`.\n\n##### .regExp(value)\n##### .date(value)\n##### .error(value)\n##### .nativePromise(value)\n##### .promise(value)\n\nReturns `true` for any object with a `.then()` and `.catch()` method. Prefer this one over `.nativePromise()` as you usually want to allow userland promise implementations too.\n\n##### .generator(value)\n\nReturns `true` for any object that implements its own `.next()` and `.throw()` methods and has a function definition for `Symbol.iterator`.\n\n##### .generatorFunction(value)\n\n##### .asyncFunction(value)\n\nReturns `true` for any `async` function that can be called with the `await` operator.\n\n```js\nis.asyncFunction(async () =\u003e {});\n//=\u003e true\n\nis.asyncFunction(() =\u003e {});\n//=\u003e false\n```\n\n##### .asyncGenerator(value)\n\n```js\nis.asyncGenerator(\n\t(async function * () {\n\t\tyield 4;\n\t})()\n);\n//=\u003e true\n\nis.asyncGenerator(\n\t(function * () {\n\t\tyield 4;\n\t})()\n);\n//=\u003e false\n```\n\n##### .asyncGeneratorFunction(value)\n\n```js\nis.asyncGeneratorFunction(async function * () {\n\tyield 4;\n});\n//=\u003e true\n\nis.asyncGeneratorFunction(function * () {\n\tyield 4;\n});\n//=\u003e false\n```\n\n##### .boundFunction(value)\n\nReturns `true` for any `bound` function.\n\n```js\nis.boundFunction(() =\u003e {});\n//=\u003e true\n\nis.boundFunction(function () {}.bind(null));\n//=\u003e true\n\nis.boundFunction(function () {});\n//=\u003e false\n```\n\n##### .map(value)\n##### .set(value)\n##### .weakMap(value)\n##### .weakSet(value)\n##### .weakRef(value)\n\n#### Typed arrays\n\n##### .int8Array(value)\n##### .uint8Array(value)\n##### .uint8ClampedArray(value)\n##### .int16Array(value)\n##### .uint16Array(value)\n##### .int32Array(value)\n##### .uint32Array(value)\n##### .float32Array(value)\n##### .float64Array(value)\n##### .bigInt64Array(value)\n##### .bigUint64Array(value)\n\n#### Structured data\n\n##### .arrayBuffer(value)\n##### .sharedArrayBuffer(value)\n##### .dataView(value)\n\n##### .enumCase(value, enum)\n\nTypeScript-only. Returns `true` if `value` is a member of `enum`.\n\n```ts\nenum Direction {\n\tAscending = 'ascending',\n\tDescending = 'descending'\n}\n\nis.enumCase('ascending', Direction);\n//=\u003e true\n\nis.enumCase('other', Direction);\n//=\u003e false\n```\n\n#### Emptiness\n\n##### .emptyString(value)\n\nReturns `true` if the value is a `string` and the `.length` is 0.\n\n##### .emptyStringOrWhitespace(value)\n\nReturns `true` if `is.emptyString(value)` or if it's a `string` that is all whitespace.\n\n##### .nonEmptyString(value)\n\nReturns `true` if the value is a `string` and the `.length` is more than 0.\n\n##### .nonEmptyStringAndNotWhitespace(value)\n\nReturns `true` if the value is a `string` that is not empty and not whitespace.\n\n```js\nconst values = ['property1', '', null, 'property2', '    ', undefined];\n\nvalues.filter(is.nonEmptyStringAndNotWhitespace);\n//=\u003e ['property1', 'property2']\n```\n\n##### .emptyArray(value)\n\nReturns `true` if the value is an `Array` and the `.length` is 0.\n\n##### .nonEmptyArray(value)\n\nReturns `true` if the value is an `Array` and the `.length` is more than 0.\n\n##### .emptyObject(value)\n\nReturns `true` if the value is an `Object` and `Object.keys(value).length` is 0.\n\nPlease note that `Object.keys` returns only own enumerable properties. Hence something like this can happen:\n\n```js\nconst object1 = {};\n\nObject.defineProperty(object1, 'property1', {\n\tvalue: 42,\n\twritable: true,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nis.emptyObject(object1);\n//=\u003e true\n```\n\n##### .nonEmptyObject(value)\n\nReturns `true` if the value is an `Object` and `Object.keys(value).length` is more than 0.\n\n##### .emptySet(value)\n\nReturns `true` if the value is a `Set` and the `.size` is 0.\n\n##### .nonEmptySet(Value)\n\nReturns `true` if the value is a `Set` and the `.size` is more than 0.\n\n##### .emptyMap(value)\n\nReturns `true` if the value is a `Map` and the `.size` is 0.\n\n##### .nonEmptyMap(value)\n\nReturns `true` if the value is a `Map` and the `.size` is more than 0.\n\n#### Miscellaneous\n\n##### .directInstanceOf(value, class)\n\nReturns `true` if `value` is a direct instance of `class`.\n\n```js\nis.directInstanceOf(new Error(), Error);\n//=\u003e true\n\nclass UnicornError extends Error {}\n\nis.directInstanceOf(new UnicornError(), Error);\n//=\u003e false\n```\n\n##### .urlInstance(value)\n\nReturns `true` if `value` is an instance of the [`URL` class](https://developer.mozilla.org/en-US/docs/Web/API/URL).\n\n```js\nconst url = new URL('https://example.com');\n\nis.urlInstance(url);\n//=\u003e true\n```\n\n##### .urlString(value)\n\nReturns `true` if `value` is a URL string.\n\nNote: this only does basic checking using the [`URL` class](https://developer.mozilla.org/en-US/docs/Web/API/URL) constructor.\n\n```js\nconst url = 'https://example.com';\n\nis.urlString(url);\n//=\u003e true\n\nis.urlString(new URL(url));\n//=\u003e false\n```\n\n##### .truthy(value)\n\nReturns `true` for all values that evaluate to true in a boolean context:\n\n```js\nis.truthy('🦄');\n//=\u003e true\n\nis.truthy(undefined);\n//=\u003e false\n```\n\n##### .falsy(value)\n\nReturns `true` if `value` is one of: `false`, `0`, `''`, `null`, `undefined`, `NaN`.\n\n##### .nan(value)\n##### .nullOrUndefined(value)\n##### .primitive(value)\n\nJavaScript primitives are as follows:\n\n- `null`\n- `undefined`\n- `string`\n- `number`\n- `boolean`\n- `symbol`\n- `bigint`\n\n##### .integer(value)\n\n##### .safeInteger(value)\n\nReturns `true` if `value` is a [safe integer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger).\n\n##### .plainObject(value)\n\nAn object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`.\n\n##### .iterable(value)\n##### .asyncIterable(value)\n##### .class(value)\n\nReturns `true` if the value is a class constructor.\n\n##### .typedArray(value)\n\n##### .arrayLike(value)\n\nA `value` is array-like if it is not a function and has a `value.length` that is a safe integer greater than or equal to 0.\n\n```js\nis.arrayLike(document.forms);\n//=\u003e true\n\nfunction foo() {\n\tis.arrayLike(arguments);\n\t//=\u003e true\n}\nfoo();\n```\n\n##### .tupleLike(value, guards)\n\nA `value` is tuple-like if it matches the provided `guards` array both in `.length` and in types.\n\n```js\nis.tupleLike([1], [is.number]);\n//=\u003e true\n```\n\n```js\nfunction foo() {\n\tconst tuple = [1, '2', true];\n\tif (is.tupleLike(tuple, [is.number, is.string, is.boolean])) {\n\t\ttuple // [number, string, boolean]\n\t}\n}\n\nfoo();\n```\n\n##### .positiveNumber(value)\n\nCheck if `value` is a number and is more than 0.\n\n##### .negativeNumber(value)\n\nCheck if `value` is a number and is less than 0.\n\n##### .inRange(value, range)\n\nCheck if `value` (number) is in the given `range`. The range is an array of two values, lower bound and upper bound, in no specific order.\n\n```js\nis.inRange(3, [0, 5]);\nis.inRange(3, [5, 0]);\nis.inRange(0, [-2, 2]);\n```\n\n##### .inRange(value, upperBound)\n\nCheck if `value` (number) is in the range of `0` to `upperBound`.\n\n```js\nis.inRange(3, 10);\n```\n\n##### .htmlElement(value)\n\nReturns `true` if `value` is an [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement).\n\n##### .nodeStream(value)\n\nReturns `true` if `value` is a Node.js [stream](https://nodejs.org/api/stream.html).\n\n```js\nimport fs from 'node:fs';\n\nis.nodeStream(fs.createReadStream('unicorn.png'));\n//=\u003e true\n```\n\n##### .observable(value)\n\nReturns `true` if `value` is an `Observable`.\n\n```js\nimport {Observable} from 'rxjs';\n\nis.observable(new Observable());\n//=\u003e true\n```\n\n##### .infinite(value)\n\nCheck if `value` is `Infinity` or `-Infinity`.\n\n##### .evenInteger(value)\n\nReturns `true` if `value` is an even integer.\n\n##### .oddInteger(value)\n\nReturns `true` if `value` is an odd integer.\n\n##### .propertyKey(value)\n\nReturns `true` if `value` can be used as an object property key (either `string`, `number`, or `symbol`).\n\n##### .formData(value)\n\nReturns `true` if `value` is an instance of the [`FormData` class](https://developer.mozilla.org/en-US/docs/Web/API/FormData).\n\n```js\nconst data = new FormData();\n\nis.formData(data);\n//=\u003e true\n```\n\n##### .urlSearchParams(value)\n\nReturns `true` if `value` is an instance of the [`URLSearchParams` class](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).\n\n```js\nconst searchParams = new URLSearchParams();\n\nis.urlSearchParams(searchParams);\n//=\u003e true\n```\n\n##### .any(predicate | predicate[], ...values)\n\nUsing a single `predicate` argument, returns `true` if **any** of the input `values` returns true in the `predicate`:\n\n```js\nis.any(is.string, {}, true, '🦄');\n//=\u003e true\n\nis.any(is.boolean, 'unicorns', [], new Map());\n//=\u003e false\n```\n\nUsing an array of `predicate[]`, returns `true` if **any** of the input `values` returns true for **any** of the `predicates` provided in an array:\n\n```js\nis.any([is.string, is.number], {}, true, '🦄');\n//=\u003e true\n\nis.any([is.boolean, is.number], 'unicorns', [], new Map());\n//=\u003e false\n```\n\n##### .any(predicate[])\n\nUsing an array of `predicate[]` without values, returns a combined type guard that checks if a value matches **any** of the predicates:\n\n```js\nconst isStringOrNumber = is.any([is.string, is.number]);\n\nisStringOrNumber('hello');\n//=\u003e true\n\nisStringOrNumber(123);\n//=\u003e true\n\nisStringOrNumber(true);\n//=\u003e false\n```\n\nThis is useful for composing with other methods like `is.optional`:\n\n```js\nis.optional(value, is.any([is.string, is.number]));\n```\n\nAn empty predicate array currently returns a predicate that always returns `false`. This will throw in the next major release.\n\n##### .all(predicate, ...values)\n\nReturns `true` if **all** of the input `values` returns true in the `predicate`:\n\n```js\nis.all(is.object, {}, new Map(), new Set());\n//=\u003e true\n\nis.all(is.string, '🦄', [], 'unicorns');\n//=\u003e false\n```\n\n##### .all(predicate[])\n\nUsing an array of `predicate[]` without values, returns a combined type guard that checks if a value matches **all** of the predicates:\n\n```js\nconst isArrayAndNonEmpty = is.all([is.array, is.nonEmptyArray]);\n\nisArrayAndNonEmpty(['hello']);\n//=\u003e true\n\nisArrayAndNonEmpty([]);\n//=\u003e false\n```\n\nThis is useful for composing with other methods like `is.optional`:\n\n```js\nis.optional(value, is.all([is.object, is.plainObject]));\n```\n\nAn empty predicate array currently returns a predicate that always returns `true`. This will throw in the next major release.\n\n##### .optional(value, predicate)\n\nReturns `true` if `value` is `undefined` or satisfies the given `predicate`.\n\n```js\nis.optional(undefined, is.string);\n//=\u003e true\n\nis.optional('🦄', is.string);\n//=\u003e true\n\nis.optional(123, is.string);\n//=\u003e false\n```\n\n##### .validDate(value)\n\nReturns `true` if the value is a valid date.\n\nAll [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) objects have an internal timestamp value which is the number of milliseconds since the [Unix epoch](https://developer.mozilla.org/en-US/docs/Glossary/Unix_time). When a new `Date` is constructed with bad inputs, no error is thrown. Instead, a new `Date` object is returned. But the internal timestamp value is set to `NaN`, which is an `'Invalid Date'`. Bad inputs can be an non-parsable date string, a non-numeric value or a number that is outside of the expected range for a date value.\n\n```js\nconst valid = new Date('2000-01-01');\n\nis.date(valid);\n//=\u003e true\nvalid.getTime();\n//=\u003e 946684800000\nvalid.toUTCString();\n//=\u003e 'Sat, 01 Jan 2000 00:00:00 GMT'\nis.validDate(valid);\n//=\u003e true\n\nconst invalid = new Date('Not a parsable date string');\n\nis.date(invalid);\n//=\u003e true\ninvalid.getTime();\n//=\u003e NaN\ninvalid.toUTCString();\n//=\u003e 'Invalid Date'\nis.validDate(invalid);\n//=\u003e false\n```\n\n##### .validLength(value)\n\nReturns `true` if the value is a safe integer that is greater than or equal to zero.\n\nThis can be useful to confirm that a value is a valid count of something, ie. 0 or more.\n\n##### .whitespaceString(value)\n\nReturns `true` if the value is a string with only whitespace characters.\n\n## Type guards\n\nWhen using `is` together with TypeScript, [type guards](http://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types) are being used extensively to infer the correct type inside if-else statements.\n\n```ts\nimport is from '@sindresorhus/is';\n\nconst padLeft = (value: string, padding: string | number) =\u003e {\n\tif (is.number(padding)) {\n\t\t// `padding` is typed as `number`\n\t\treturn Array(padding + 1).join(' ') + value;\n\t}\n\n\tif (is.string(padding)) {\n\t\t// `padding` is typed as `string`\n\t\treturn padding + value;\n\t}\n\n\tthrow new TypeError(`Expected 'padding' to be of type 'string' or 'number', got '${is(padding)}'.`);\n}\n\npadLeft('🦄', 3);\n//=\u003e '   🦄'\n\npadLeft('🦄', '🌈');\n//=\u003e '🌈🦄'\n```\n\n## Type assertions\n\nThe type guards are also available as [type assertions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions), which throw an error for unexpected types. It is a convenient one-line version of the often repetitive \"if-not-expected-type-throw\" pattern.\n\n```ts\nimport {assert} from '@sindresorhus/is';\n\nconst handleMovieRatingApiResponse = (response: unknown) =\u003e {\n\tassert.plainObject(response);\n\t// `response` is now typed as a plain `object` with `unknown` properties.\n\n\tassert.number(response.rating);\n\t// `response.rating` is now typed as a `number`.\n\n\tassert.string(response.title);\n\t// `response.title` is now typed as a `string`.\n\n\treturn `${response.title} (${response.rating * 10})`;\n};\n\nhandleMovieRatingApiResponse({rating: 0.87, title: 'The Matrix'});\n//=\u003e 'The Matrix (8.7)'\n\n// This throws an error.\nhandleMovieRatingApiResponse({rating: '🦄'});\n```\n\n### Optional assertion\n\nAsserts that `value` is `undefined` or satisfies the provided `assertion`.\n\n```ts\nimport {assert} from '@sindresorhus/is';\n\nassert.optional(undefined, assert.string);\n// Passes without throwing\n\nassert.optional('🦄', assert.string);\n// Passes without throwing\n\nassert.optional(123, assert.string);\n// Throws: Expected value which is `string`, received value of type `number`\n```\n\n## Generic type parameters\n\nThe type guards and type assertions are aware of [generic type parameters](https://www.typescriptlang.org/docs/handbook/generics.html), such as `Promise\u003cT\u003e` and `Map\u003cKey, Value\u003e`. The default is `unknown` for most cases, since `is` cannot check them at runtime. If the generic type is known at compile-time, either implicitly (inferred) or explicitly (provided), `is` propagates the type so it can be used later.\n\nUse generic type parameters with caution. They are only checked by the TypeScript compiler, and not checked by `is` at runtime. This can lead to unexpected behavior, where the generic type is _assumed_ at compile-time, but actually is something completely different at runtime. It is best to use `unknown` (default) and type-check the value of the generic type parameter at runtime with `is` or `assert`.\n\n```ts\nimport {assert} from '@sindresorhus/is';\n\nasync function badNumberAssumption(input: unknown) {\n\t// Bad assumption about the generic type parameter fools the compile-time type system.\n\tassert.promise\u003cnumber\u003e(input);\n\t// `input` is a `Promise` but only assumed to be `Promise\u003cnumber\u003e`.\n\n\tconst resolved = await input;\n\t// `resolved` is typed as `number` but was not actually checked at runtime.\n\n\t// Multiplication will return NaN if the input promise did not actually contain a number.\n\treturn 2 * resolved;\n}\n\nasync function goodNumberAssertion(input: unknown) {\n\tassert.promise(input);\n\t// `input` is typed as `Promise\u003cunknown\u003e`\n\n\tconst resolved = await input;\n\t// `resolved` is typed as `unknown`\n\n\tassert.number(resolved);\n\t// `resolved` is typed as `number`\n\n\t// Uses runtime checks so only numbers will reach the multiplication.\n\treturn 2 * resolved;\n}\n\nbadNumberAssumption(Promise.resolve('An unexpected string'));\n//=\u003e NaN\n\n// This correctly throws an error because of the unexpected string value.\ngoodNumberAssertion(Promise.resolve('An unexpected string'));\n```\n\n## FAQ\n\n### Why yet another type checking module?\n\nThere are hundreds of type checking modules on npm, unfortunately, I couldn't find any that fit my needs:\n\n- Includes both type methods and ability to get the type\n- Types of primitives returned as lowercase and object types as camelcase\n- Covers all built-ins\n- Unsurprising behavior\n- Well-maintained\n- Comprehensive test suite\n\nFor the ones I found, pick 3 of these.\n\nThe most common mistakes I noticed in these modules was using `instanceof` for type checking, forgetting that functions are objects, and omitting `symbol` as a primitive.\n\n### Why not just use `instanceof` instead of this package?\n\n`instanceof` does not work correctly for all types and it does not work across [realms](https://stackoverflow.com/a/49832343/64949). Examples of realms are iframes, windows, web workers, and the `vm` module in Node.js.\n\n## Related\n\n- [environment](https://github.com/sindresorhus/environment) - Check which JavaScript environment your code is running in at runtime\n- [is-stream](https://github.com/sindresorhus/is-stream) - Check if something is a Node.js stream\n- [is-observable](https://github.com/sindresorhus/is-observable) - Check if a value is an Observable\n- [file-type](https://github.com/sindresorhus/file-type) - Detect the file type of a Buffer/Uint8Array\n- [is-ip](https://github.com/sindresorhus/is-ip) - Check if a string is an IP address\n- [is-array-sorted](https://github.com/sindresorhus/is-array-sorted) - Check if an Array is sorted\n- [is-error-constructor](https://github.com/sindresorhus/is-error-constructor) - Check if a value is an error constructor\n- [is-empty-iterable](https://github.com/sindresorhus/is-empty-iterable) - Check if an Iterable is empty\n- [is-blob](https://github.com/sindresorhus/is-blob) - Check if a value is a Blob - File-like object of immutable, raw data\n- [has-emoji](https://github.com/sindresorhus/has-emoji) - Check whether a string has any emoji\n\n## Maintainers\n\n- [Sindre Sorhus](https://github.com/sindresorhus)\n- [Giora Guttsait](https://github.com/gioragutt)\n- [Brandon Smith](https://github.com/brandon93s)\n","funding_links":["https://github.com/sponsors/sindresorhus","https://opencollective.com/sindresorhus","https://buymeacoffee.com/sindresorhus","https://sindresorhus.com/donate"],"categories":["TypeScript","Packages","包","typescript","Miscellaneous","Framework agnostic packages"],"sub_categories":["Miscellaneous","杂项","其他","General utilities"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Fis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsindresorhus%2Fis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Fis/lists"}