{"id":43432562,"url":"https://github.com/slikts/tuplerone","last_synced_at":"2026-02-02T19:29:47.114Z","repository":{"id":48272323,"uuid":"141041018","full_name":"slikts/tuplerone","owner":"slikts","description":"Tuples and value objects for JavaScript 🤷","archived":false,"fork":false,"pushed_at":"2023-08-02T12:52:16.000Z","size":231510,"stargazers_count":63,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-04T22:14:58.872Z","etag":null,"topics":["cache","data-structures","equality-test","es2015","immutability","memoization","tuples","value-objects","value-semantics"],"latest_commit_sha":null,"homepage":"https://tuplerone.js.org","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/slikts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2018-07-15T16:14:44.000Z","updated_at":"2025-02-24T18:06:15.000Z","dependencies_parsed_at":"2024-06-18T22:41:28.948Z","dependency_job_id":"8861b3b5-6e70-467e-b58f-53bb5ccc0fde","html_url":"https://github.com/slikts/tuplerone","commit_stats":{"total_commits":414,"total_committers":3,"mean_commits":138.0,"dds":"0.21014492753623193","last_synced_commit":"3d10b9e716207309a74d20659f8ea7fdc7cd6cdf"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/slikts/tuplerone","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slikts%2Ftuplerone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slikts%2Ftuplerone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slikts%2Ftuplerone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slikts%2Ftuplerone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slikts","download_url":"https://codeload.github.com/slikts/tuplerone/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slikts%2Ftuplerone/sbom","scorecard":{"id":831664,"data":{"date":"2025-08-11","repo":{"name":"github.com/slikts/tuplerone","commit":"19494b9c52780459f7d8f92ecf0b49471a871480"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.4,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 21 changesets","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"44 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-v39p-96qg-c8rf","Warn: Project is vulnerable to: GHSA-8v63-cqqc-6r2c","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T17:55:58.843Z","repository_id":48272323,"created_at":"2025-08-23T17:55:58.843Z","updated_at":"2025-08-23T17:55:58.843Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29017962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T18:51:31.335Z","status":"ssl_error","status_checked_at":"2026-02-02T18:49:20.777Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["cache","data-structures","equality-test","es2015","immutability","memoization","tuples","value-objects","value-semantics"],"created_at":"2026-02-02T19:29:46.958Z","updated_at":"2026-02-02T19:29:47.100Z","avatar_url":"https://github.com/slikts.png","language":"TypeScript","readme":"\u003ch1 align=\"center\"\u003e\u003ca href=\"https://github.com/slikts/tuplerone\"\u003e\u003cimg width=\"550\" src=\"https://raw.githubusercontent.com/slikts/tuplerone/master/logo.svg?sanitize=true\" alt=\"tuplerone\"\u003e\u003c/a\u003e\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://travis-ci.org/slikts/tuplerone\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/tuplerone.svg?style=flat\" alt=\"View this project on npm\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://travis-ci.org/slikts/tuplerone\"\u003e\u003cimg src=\"https://img.shields.io/travis/slikts/tuplerone.svg\" alt=\"Travis\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/slikts/tuplerone\"\u003e\u003cimg src=\"https://img.shields.io/coveralls/slikts/tuplerone.svg\" alt=\"Coveralls\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://david-dm.org/slikts/tuplerone?type=dev\"\u003e\u003cimg src=\"https://david-dm.org/slikts/tuplerone/dev-status.svg\" alt=\"Dev Dependencies\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\" alt=\"semantic-release\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://badgen.net/dependabot/slikts/tuplerone\" alt=\"Dependabot\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eA lightweight, efficient tuple and value object implementation for JavaScript and TypeScript.\u003c/p\u003e\n\n---\n\nA quick reminder about what tuples are (using Python):\n\n```python\n(1, 2, 3) == (1, 2, 3) # → True\n```\n\nA JavaScript version of something similar looks like this:\n\n```js\n'[1,2,3]' === '[1,2,3]'; // → true\n```\n\nExcept it's using a string and would need to be unserialized with `JSON.parse()` to allow accessing the separate members. Moreover, JSON is limited in what values can be serialized.\n\nYou could alternatively use `\"1,2,3\"` and `String.split(\",\")`, but it's also not very convenient. Just using an array doesn't work:\n\n```js\n[1, 2, 3] === [1, 2, 3]; // → false\n```\n\nEach JavaScript array is a different object and so its value is the reference to that object. Tuples are a way to make that reference the same if the array members are the same. Using Tuplerone:\n\n```js\nTuple(1, 2, 3) === Tuple(1, 2, 3);\n```\n\nExample use case for tuples is dealing with memoization like React's [`memo()`][memo] or `PureComponent`, since you can pass lists as props to components without forcing re-renders or manually caching the list. It's also useful for using multiple values as keys with `Map()`. In general, it's just a nice thing to have in your toolbox.\n\n**[Try Tuplerone in a sandbox][sandbox]**\n\n---\n\nThis library is:\n\n- _tiny_ (bundle size is [under one kilobyte][tiny] compressed), with no dependencies\n- _well-typed_ using TypeScript (but can still be used from JavaScript, of course)\n- _well-tested_ with full coverage\n- _efficient_ using an ES2015 [`WeakMap`][weakmap]-based directed acyclic graph for lookups\n\nThe `Tuple` objects are:\n\n- _immutable_ – properties cannot be added, removed or changed, and it's enforced with [`Object.freeze()`][frozen]\n- [array-like] – tuple members can be accessed by indexing, and there's a `length` property, but no `Array` prototype methods\n- [iterable] – tuple members can be iterated over, for example, using [`for-of`][for-of] loops or spread syntax\n\nThere exists a [stage-1 proposal][proposal] for adding a tuple type to JavaScript and a [different stage-1 proposal][composite] for adding a more limited value-semantic type.\n\n## Theory\n\n[Tuples] are **finite ordered sequences of values** that serve two main purposes in programming languages:\n\n- grouping together heterogenous (mixed) data types within a static type system (this doesn't apply to a dynamically typed language like JavaScript)\n- simplifying value-semantic comparisons of lists, which is what this library is mainly about\n\n### Value semantics\n\nA simple way to explain value semantics is to look at the difference between primitive values (like numbers and strings) and object values in JavaScript. Primitives are value-semantic by default,\nmeaning that the default comparison methods (`==`, `===` and `Object.is()`) compare primitive values by their contents, so, for example, any string is equal to any other string created with the same contents:\n\n```js\n'abc' === 'abc'; // → true, because both string literals create a value with the same contents\n```\n\nThe contents of primitive values are also immutable (can't change at runtime), so the results of comparing primitive value equality can't be invalidated by the contents of the values changing.\n\nMeanwhile, each object value (instance) in JavaScript has a unique identity, so each instance is only equal to itself and not any other instances:\n\n```js\n[1, 2, 3] === [1, 2, 3]; // → false, because both array literals create separate array instances\n```\n\nObjects by default can't be thought of as their contents since the contents can change, and this is called reference semantics, since objects essentially represent a place in memory. The downside is that it makes reasoning about a program harder, since the programmer has to consider potential changes.\n\nA more direct practical consequence of reference semantics is that comparing instances requires _deep comparisons_, such as [`_.isEqual()`][isequal] in lodash or serializing the object values to JSON:\n\n```js\nlet a = [1, 2, 3];\nlet b = [1, 2, 3];\nlet result = JSON.stringify(a) === JSON.stringify(b); // → true, because it's a deep comparison\na.push(4); // a and b contents are now different, so the cached comparison result is invalid\n```\n\nDeep comparison results can't be reliably cached since the compared instances can change, and it's also less efficient than just being able to use `===` directly. An another thing that's not possible with reference semantics is combining different values to use as a composite key (such as with `Map` or `WeakMap`).\n\n### Directed acyclic graphs\n\nDirected acyclic graphs (DAGs) are a data structure that allows efficiently mapping a sequence of values to a unique object containing them, which is how this library is implemented. Specifically, it uses a `WeakMap` object (optionally a `Map` as well if mapping primitives) for each node, and the nodes are re-used for overlapping paths in the graph. Map access has constant time complexity, so the number of tuples created doesn't slow down access speed. Using `WeakMap` ensures that if the values used to create the tuple are dereferenced, the tuple object gets garbage collected.\n\n## Installation\n\n### npm\n\n```\nnpm install tuplerone\n```\n\n### yarn\n\n```\nyarn add tuplerone\n```\n\n### CDN\n\nhttps://unpkg.com/tuplerone/dist/tuplerone.umd.js\n\n## Usage\n\n### `Tuple(…values)`\n\n```js\nimport { Tuple } from 'tuplerone';\n\n// Dummy objects\nconst a = Object('a');\nconst b = Object('b');\nconst c = Object('c');\n\n// Structural equality testing using the identity operator\nTuple(a, b, c) === Tuple(a, b, c); // → true\nTuple(a, b) === Tuple(b, a); // → false\n\n// Mapping using a pair of values as key\nconst map = new Map();\nmap.set(Tuple(a, b), 123).get(Tuple(a, b)); // → 123\n\n// Nesting tuples\nTuple(a, Tuple(b, c)) === Tuple(a, Tuple(b, c)); // → true\n\n// Using primitive values\nTuple(1, 'a', a); // → Tuple(3) [1, \"a\", Object(\"a\")]\n\n// Indexing\nTuple(a, b)[1]; // → Object(\"b\")\n\n// Checking arity\nTuple(a, b).length; // → 2\n\n// Failing to mutate\nTuple(a, b)[0] = c; // throws an error\n```\n\nThe tuple function caches or memoizes its arguments to produce the same tuple object for the same arguments.\n\n### Types\n\nThe library is well-typed using TypeScript:\n\n```ts\nimport { Tuple, Tuple0, Tuple1, Tuple2 } from 'tuplerone';\n\n// Dummy object for use as key\nconst o = {};\n\nconst tuple0: Tuple0 = Tuple(); // 0-tuple\nconst tuple1: Tuple1\u003ctypeof o\u003e = Tuple(o); // 1-tuple\nconst tuple2: Tuple2\u003ctypeof o, number\u003e = Tuple(o, 1); // 2-tuple\n\nTuple(o) === Tuple(o, 1); // TS compile error due to different arities\n\n// Spreading a TypeScript tuple:\nTuple(...([1, 2, 3] as const)); // → Tuple3\u003c1, 2, 3\u003e\n```\n\nIn editors like VS Code, the type information is also available when the library is consumed as JavaScript.\n\n### `CompositeSymbol(…values)`\n\nIt's possible to avoid creating an `Array`-like tuple for cases where iterating the tuple members isn't needed (for example, just to use it as a key):\n\n```js\nimport { CompositeSymbol } from 'tuplerone';\n\ntypeof CompositeSymbol(1, 2, {}) === 'symbol'; // → true\n```\n\nA symbol is more space efficient than a tuple and can be used as a key for plain objects.\n\n### `ValueObject(object)`\n\nTuplerone also includes a simple [value object] implementation:\n\n```js\nimport { ValueObject } from 'tuplerone';\n\nValueObject({ a: 1, { b: { c: 2 } }}) === ValueObject({ a: 1, { b: { c: 2 } }}); // → true\n```\n\nNote that the passed objects are frozen with [`Object.freeze()`][frozen].\n\n## Caveats\n\nSince this is a userspace implementation, there are a number of limitations.\n\n### At least one member must be an object to avoid memory leaks\n\nDue to `WeakMap` being limited to using objects as keys, there must be at least one member of a tuple with the object type, or the tuples would leak memory. Trying to create tuples with only primitive members will throw an error.\n\n```ts\nTuple(1, 2); // throws TypeError\nTuple(1, 2, {}); // works\n```\n\n`WeakMap` is an ES2015 feature which is difficult to polyfill (the [polyfills][polyfill] don't support frozen objects), but this applies less to environments like node or browser extensions.\n\n#### `UnsafeTuple`\n\nThere is an `UnsafeTuple` type for advanced use cases where the values not being garbage-collectable is acceptable, so it doesn't require having an object member:\n\n```js\nimport { UnsafeTuple as Tuple } from 'tuplerone';\n\nTuple(1, 2, 3) === Tuple(1, 2, 3); // → true\n```\n\n### Can't be compared with operators like `\u003c` or `\u003e`\n\ntuplerone tuples are not supported by the relation comparison operators like `\u003c`, whereas in a language like Python the following (comparing tuples by arity) would evaluate to true: `(1,) \u003c (1, 2)`.\n\n### `Array`-like but there's no `Array` prototypes methods\n\nTuples subclass `Array`:\n\n```typescript\nArray.isArray(Tuple()); // → true\n```\n\nYet tuples don't support mutative `Array` prototype methods like `Array.sort()`, since tuples are frozen.\n\nThe advantage of subclassing `Array` is ergonomic console representation (it's represented as an array would be), which is based on `Array.isArray()` and so requires subclassing `Array`.\n\n### Limited number of arities\n\nThe tuples are currently typed up to 8-tuple (octuple) because TypeScript doesn't yet support [variadic generics]. The types are implemented using function overloads.\n\n### `instanceof` doesn't work as expected\n\nTuples can be constructed without the `new` keyword to make them behave like other primitive values\n(`Symbol`, `Boolean`, `String`, `Number`) that also don't require `new` and also are value-semantic. This means that `instanceof` doesn't work the same as for other objects, but can still be used like so:\n\n```js\nTuple() instanceof Tuple.constructor; // → true\n```\n\n## License\n\nMIT\n\n## Author\n\nslikts \u003cdabas@untu.ms\u003e\n\n[weakmap]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap\n[map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map\n[tuples]: https://en.wiktionary.org/wiki/tuple\n[isequal]: https://lodash.com/docs/4.17.10#isEqual\n[frozen]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze\n[composite]: https://github.com/bmeck/proposal-richer-keys/tree/master/compositeKey\n[iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol\n[tuple]: https://en.wiktionary.org/wiki/tuple\n[array-like]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#Working_with_array-like_objects\n[for-of]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of\n[tiny]: https://bundlephobia.com/result?p=tuplerone\n[polyfill]: https://github.com/medikoo/es6-weak-map#readme\n[value semantics]: https://en.wikipedia.org/wiki/Value_semantics\n[value types]: https://en.wikipedia.org/wiki/Value_type_and_reference_type\n[isequal]: https://lodash.com/docs/#isEqual\n[proposal]: https://github.com/tc39/proposal-record-tuple\n[memo]: https://reactjs.org/docs/react-api.html#reactmemo\n[variadic generics]: https://github.com/microsoft/TypeScript/issues/5453\n[sandbox]: https://codesandbox.io/s/tuplerone-dm90w?expanddevtools=1\n[value object]: https://en.wikipedia.org/wiki/Value_object\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslikts%2Ftuplerone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslikts%2Ftuplerone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslikts%2Ftuplerone/lists"}