{"id":13528274,"url":"https://github.com/sindresorhus/ts-extras","last_synced_at":"2026-04-01T23:51:06.372Z","repository":{"id":38345671,"uuid":"417489028","full_name":"sindresorhus/ts-extras","owner":"sindresorhus","description":"Essential utilities for TypeScript projects","archived":false,"fork":false,"pushed_at":"2026-03-22T16:31:29.000Z","size":136,"stargazers_count":760,"open_issues_count":1,"forks_count":23,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-23T07:41:30.242Z","etag":null,"topics":[],"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":{"funding":{"github":"sindresorhus","open_collective":"sindresorhus","buy_me_a_coffee":"sindresorhus","custom":"https://sindresorhus.com/donate"},"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-15T12:19:22.000Z","updated_at":"2026-03-22T20:28:31.000Z","dependencies_parsed_at":"2023-12-19T05:56:17.557Z","dependency_job_id":"bfc1da61-c85c-4bf2-918d-22c512d445ae","html_url":"https://github.com/sindresorhus/ts-extras","commit_stats":{"total_commits":51,"total_committers":9,"mean_commits":5.666666666666667,"dds":0.4117647058823529,"last_synced_commit":"5dd1252cc80929614b4e8066232102d2673e24dd"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/sindresorhus/ts-extras","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fts-extras","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fts-extras/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fts-extras/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fts-extras/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sindresorhus","download_url":"https://codeload.github.com/sindresorhus/ts-extras/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Fts-extras/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-08-01T06:02:23.047Z","updated_at":"2026-04-01T23:51:06.345Z","avatar_url":"https://github.com/sindresorhus.png","language":"TypeScript","funding_links":["https://github.com/sponsors/sindresorhus","https://opencollective.com/sindresorhus","https://buymeacoffee.com/sindresorhus","https://sindresorhus.com/donate"],"categories":["TypeScript",":books: Libraries"],"sub_categories":["Universal"],"readme":"# ts-extras [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://giphy.com/gifs/illustration-rainbow-unicorn-26AHG5KGFxSkUWw1i) [![npm dependents](https://badgen.net/npm/dependents/ts-extras)](https://www.npmjs.com/package/ts-extras?activeTab=dependents) [![npm downloads](https://badgen.net/npm/dt/ts-extras)](https://www.npmjs.com/package/ts-extras)\n\n\u003e Essential utilities for TypeScript projects\n\n*Ideas for additional **essential** utilities welcome. Type-only utilities belong in [type-fest](https://github.com/sindresorhus/type-fest).*\n\n## Install\n\n```sh\nnpm install ts-extras\n```\n\n## Usage\n\n```js\nimport {isDefined} from 'ts-extras';\n\n[1, undefined, 2].filter(isDefined);\n//=\u003e [1, 2]\n```\n\n## API\n\n**General**\n\n- [`asWritable`](source/as-writable.ts) - Cast the given value to be [`Writable`](https://github.com/sindresorhus/type-fest/blob/main/source/writable.d.ts).\n- [`safeCastTo`](source/safe-cast-to.ts) - Constrain a value to the given type safely.\n\n**Type guard**\n\n- [`isDefined`](source/is-defined.ts) - Check whether a value is defined (not `undefined`).\n- [`isEqualType`](source/is-equal-type.ts) - Check if two types are equal at compile time.\n- [`isPresent`](source/is-present.ts) - Check whether a value is present (not `null` nor `undefined`).\n- [`isPropertyDefined`](source/is-property-defined.ts) - Check whether a specific property of a value is defined (not `undefined`).\n- [`isPropertyPresent`](source/is-property-present.ts) - Check whether a specific property of a value is present (not `null` nor `undefined`).\n- [`isEmpty`](source/is-empty.ts) - Check whether an array is empty.\n- [`isFinite`](source/is-finite.ts) - A strongly-typed version of `Number.isFinite()`.\n- [`isInfinite`](source/is-infinite.ts) - Check whether a value is infinite.\n- [`isInteger`](source/is-integer.ts) - A strongly-typed version of `Number.isInteger()`.\n- [`isSafeInteger`](source/is-safe-integer.ts) - A strongly-typed version of `Number.isSafeInteger()`.\n- [`keyIn`](source/key-in.ts) - Check if a key is in an object and narrow the key to the object's keys.\n- [`not`](source/not.ts) - Invert a type predicate function.\n- [`objectHasIn`](source/object-has-in.ts) - Check if an object has a property (including inherited) and narrow the object type.\n- [`assertDefined`](source/assert-defined.ts) - Assert that the given value is defined, meaning it is not `undefined`.\n- [`assertPresent`](source/assert-present.ts) - Assert that the given value is present (non-nullable), meaning it is neither `null` nor `undefined`.\n- [`assertError`](source/assert-error.ts) - Assert that the given value is an `Error`.\n\n**Improved builtin**\n\n- [`arrayAt`](source/array-at.ts) - A strongly-typed version of `Array#at()` with improved tuple support (supports `-1` and positive literal indices for tuples).\n- [`arrayConcat`](source/array-concat.ts) - A strongly-typed version of `Array#concat()` that properly handles arrays of different types.\n- [`arrayJoin`](source/array-join.ts) - A strongly-typed version of `Array#join()` that preserves literal string types.\n- [`arrayFirst`](source/array-first.ts) - Return the first item of an array with stronger typing for tuples.\n- [`arrayIncludes`](source/array-includes.ts) - A strongly-typed version of `Array#includes()` that properly acts as a type guard.\n- [`arrayLast`](source/array-last.ts) - Return the last item of an array with stronger typing for tuples.\n- [`objectKeys`](source/object-keys.ts) - A strongly-typed version of `Object.keys()`.\n- [`objectValues`](source/object-values.ts) - A strongly-typed version of `Object.values()`.\n- [`objectEntries`](source/object-entries.ts) - A strongly-typed version of `Object.entries()`.\n- [`objectFromEntries`](source/object-from-entries.ts) - A strongly-typed version of `Object.fromEntries()`.\n- [`objectMapValues`](source/object-map-values.ts) - Map over an object's values while preserving strongly-typed keys.\n- [`objectHasOwn`](source/object-has-own.ts) - A strongly-typed version of `Object.hasOwn()`.\n- [`setHas`](source/set-has.ts) - A strongly-typed version of `Set#has()` that properly acts as a type guard.\n- [`stringSplit`](source/string-split.ts) - A strongly-typed version of `String#split()` that returns a tuple for literal strings.\n\n## FAQ\n\n#### What is the difference between `keyIn`, `objectHasIn`, and `objectHasOwn`?\n\nThese functions solve different problems despite all checking property existence:\n\n**`keyIn`** - **Key narrowing** for union types:\n- Uses the `in` operator, checking the prototype chain\n- Narrows the *key* variable to only keys that exist in the object\n- Best for: \"Which of these possible keys actually exists?\"\n- Guards against `__proto__` and `constructor` for security\n\n**`objectHasIn`** - **Object narrowing** with prototype chain:\n- Uses the `in` operator, checking the prototype chain\n- Narrows the *object* type to include the checked property\n- Best for: \"Can I safely access this property (including inherited)?\"\n- Guards against `__proto__` and `constructor` for security\n\n**`objectHasOwn`** - **Object narrowing** for own properties:\n- Uses `Object.hasOwn()`, checking only own properties\n- Narrows the *object* type to include the checked property\n- Best for: \"Can I safely access this own property on this object?\"\n\n```typescript\n// keyIn - narrows the key (prototype chain)\nconst key = 'foo' as 'foo' | 'bar' | 'baz';\nif (keyIn(object, key)) {\n\t// `key` is now: 'foo' | 'bar' (only existing keys)\n\tconsole.log(object[key]); // Safe\n}\n\n// objectHasIn - narrows the object (prototype chain)\nconst data: unknown = {foo: 1};\nif (objectHasIn(data, 'toString')) {\n\t// `data` is now: unknown \u0026 {toString: unknown}\n\tconsole.log(data.toString); // Safe (inherited method)\n}\n\n// objectHasOwn - narrows the object (own properties only)\nif (objectHasOwn(data, 'foo')) {\n\t// `data` is now: unknown \u0026 {foo: unknown}\n\tconsole.log(data.foo); // Safe (own property)\n}\n```\n\n#### What is the difference between this and `type-fest`?\n\nThe `type-fest` package contains only types, meaning they are only used at compile-time and nothing is ever compiled into actual JavaScript code. This package contains functions that are compiled into JavaScript code and used at runtime.\n\n## Related\n\n- [type-fest](https://github.com/sindresorhus/type-fest) - A collection of essential TypeScript types\n- [is](https://github.com/sindresorhus/is) - Type guards for any situation\n- [camelcase-keys](https://github.com/sindresorhus/camelcase-keys) - Runtime transformation of object properties to camel-case (like `type-fest`'s `CamelCasedPropertiesDeep`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Fts-extras","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsindresorhus%2Fts-extras","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Fts-extras/lists"}