{"id":13683344,"url":"https://github.com/ksxnodemodules/typescript-tuple","last_synced_at":"2026-01-14T03:24:22.910Z","repository":{"id":41423621,"uuid":"148011446","full_name":"ksxnodemodules/typescript-tuple","owner":"ksxnodemodules","description":"Generics to work with tuples in TypeScript","archived":true,"fork":false,"pushed_at":"2023-08-03T06:34:02.000Z","size":210,"stargazers_count":156,"open_issues_count":7,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-19T18:16:17.376Z","etag":null,"topics":["generic","tuple","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/typescript-tuple","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/ksxnodemodules.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":null,"patreon":"khai96_","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-09-09T09:33:23.000Z","updated_at":"2024-10-24T11:42:09.000Z","dependencies_parsed_at":"2024-01-06T08:15:46.851Z","dependency_job_id":null,"html_url":"https://github.com/ksxnodemodules/typescript-tuple","commit_stats":{"total_commits":165,"total_committers":4,"mean_commits":41.25,"dds":"0.054545454545454564","last_synced_commit":"9a5e04ef72288ee1f9cf1561f15027ecaa356de9"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/ksxnodemodules/typescript-tuple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksxnodemodules%2Ftypescript-tuple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksxnodemodules%2Ftypescript-tuple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksxnodemodules%2Ftypescript-tuple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksxnodemodules%2Ftypescript-tuple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ksxnodemodules","download_url":"https://codeload.github.com/ksxnodemodules/typescript-tuple/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksxnodemodules%2Ftypescript-tuple/sbom","scorecard":{"id":571780,"data":{"date":"2025-08-11","repo":{"name":"github.com/ksxnodemodules/typescript-tuple","commit":"9a5e04ef72288ee1f9cf1561f15027ecaa356de9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.1,"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":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"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":0,"reason":"Found 1/21 approved changesets -- score normalized to 0","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.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md: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":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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 12 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":3,"reason":"7 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh"],"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-20T16:32:23.960Z","repository_id":41423621,"created_at":"2025-08-20T16:32:23.960Z","updated_at":"2025-08-20T16:32:23.960Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["generic","tuple","typescript"],"created_at":"2024-08-02T13:02:08.094Z","updated_at":"2026-01-14T03:24:22.891Z","avatar_url":"https://github.com/ksxnodemodules.png","language":"TypeScript","funding_links":["https://patreon.com/khai96_"],"categories":["TypeScript"],"sub_categories":[],"readme":"# TypeScript Tuple\n\nGenerics to work with tuples in TypeScript\n\n## Requirements\n\n* TypeScript ≥ 4.1.0\n\n## Usage\n\n### `IsFinite`\n\n```typescript\nimport { IsFinite } from 'typescript-tuple'\n\ntype Foo = IsFinite\u003c[0, 1, 2]\u003e // Expect: true\nconst foo: Foo = true\n\ntype Bar = IsFinite\u003c[0, 1, 2, ...number[]]\u003e // Expect: false\nconst bar: Bar = false\n\ntype Baz = IsFinite\u003c[0, 1, 2], 'finite', 'infinite'\u003e // Expect: 'finite'\nconst baz: Baz = 'finite'\n```\n\n### `First`\n\n```typescript\nimport { First } from 'typescript-tuple'\ntype Foo = First\u003c['a', 'b', 'c']\u003e // Expect: 'a'\nconst foo: Foo = 'a'\n```\n\n### `Last`\n\n```typescript\nimport { Last } from 'typescript-tuple'\ntype Foo = Last\u003c['a', 'b', 'c']\u003e // Expect: 'c'\nconst foo: Foo = 'c'\n```\n\n### `Tail`\n\n```typescript\nimport { Tail } from 'typescript-tuple'\ntype Foo = Tail\u003c['a', 'b', 'c']\u003e // Expect: ['b', 'c']\nconst foo: Foo = ['b', 'c']\n```\n\n### `Append`\n\n```typescript\nimport { Append } from 'typescript-tuple'\ntype Foo = Append\u003c['a', 'b', 'c'], 'x'\u003e // Expect: ['a', 'b', 'c', 'x']\nconst foo: Foo = ['a', 'b', 'c', 'x']\n```\n\n### `Prepend`\n\n```typescript\nimport { Prepend } from 'typescript-tuple'\ntype Foo = Prepend\u003c['a', 'b', 'c'], 'x'\u003e // Expect: ['x', 'a', 'b', 'c']\nconst foo: Foo = ['x', 'a', 'b', 'c']\n```\n\n### `Reverse`\n\n```typescript\nimport { Reverse } from 'typescript-tuple'\ntype Foo = Reverse\u003c['a', 'b', 'c']\u003e // Expect: ['c', 'b', 'a']\nconst foo: Foo = ['c', 'b', 'a']\n```\n\n### `Concat`\n\n```typescript\nimport { Concat } from 'typescript-tuple'\ntype Foo = Concat\u003c['a', 'b', 'c'], [0, 1, 2]\u003e // Expect ['a', 'b', 'c', 0, 1, 2]\nconst foo: Foo = ['a', 'b', 'c', 0, 1, 2]\n```\n\n### `Repeat`\n\n```typescript\nimport { Repeat } from 'typescript-tuple'\n\n// Basic\ntype Foo = Repeat\u003c'x', 5\u003e // Expect ['x', 'x', 'x', 'x', 'x']\nconst foo: Foo = ['x', 'x', 'x', 'x', 'x']\n\n// Using union\ntype Bar = Repeat\u003c'x', 1 | 3 | 4\u003e // Expect ['x'] | ['x', 'x', 'x'] | ['x', 'x', 'x', 'x']\nconst bar1: Bar = ['x']\nconst bar3: Bar = ['x', 'x', 'x']\nconst bar4: Bar = ['x', 'x', 'x', 'x']\n\n// Using ambiguous 'number' type\ntype Baz = Repeat\u003c'x', number\u003e // Expect 'x'[]\nconst baz: Baz = Array\u003cnumber\u003e()\n```\n\n**NOTES:**\n\n* Due to TypeScript design limitations, using floating point numbers and negative numbers might lead to infinite loop within TSC compiler, avoid doing this.\n\n### `ConcatMultiple`\n\n```typescript\nimport { ConcatMultiple } from 'typescript-tuple'\ntype Foo = ConcatMultiple\u003c[[], ['a'], ['b', 'c']]\u003e // Expect ['a', 'b', 'c']\nconst foo: Foo = ['a', 'b', 'c']\n```\n\n### `Drop`\n\n```typescript\nimport { Drop } from 'typescript-tuple'\n\ntype Foo = Drop\u003c[0, 1, 2, 3, 4], 2\u003e // Expect [2, 3, 4]\nconst foo: Foo = [2, 3, 4]\n\ntype Bar = Drop\u003c[0, 1, 2, 3, 4, ...number[]], 2\u003e // Expect [2, 3, 4, ...number[]]\nconst bar: Bar = [2, 3, 4]\n\ntype Baz = Drop\u003c[0, 1, 2, 3, 4], 10\u003e // Expect []\nconst baz: Baz = [2, 3, 4]\n\ntype Qux = Drop\u003c[0, 1, 2, 3, 4, ...number[]], 10\u003e // Expect number[]\nconst qux: Qux = [2, 3, 4]\n```\n\n### `SliceStartQuantity`\n\n```typescript\nimport { SliceStartQuantity } from 'typescript-tuple'\ntype Foo = SliceStartQuantity\u003c[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 4\u003e // Expect [2, 3, 4, 5]\nconst foo: Foo = [2, 3, 4, 5]\n```\n\n### `FillTuple`\n\n```typescript\nimport { FillTuple } from 'typescript-tuple'\ntype Foo = FillTuple\u003c[0, 1, 2, 3], 'r'\u003e\nconst foo: Foo = ['r', 'r', 'r', 'r']\n```\n\n### `CompareLength`\n\n```typescript\nimport { CompareLength } from 'typescript-tuple'\n\ntype Foo = CompareLength\u003c[0, 1, 2], ['a', 'b', 'c']\u003e // Expect: 'equal'\nconst foo: Foo = 'equal'\n\ntype Bar = CompareLength\u003c[0, 1], ['a', 'b', 'c', 'd']\u003e // Expect: 'shorterLeft'\nconst bar: Bar = 'shorterLeft'\n\ntype Baz = CompareLength\u003c[0, 1, 2, 3], ['a', 'b']\u003e // Expect: 'shorterRight'\nconst baz: Baz = 'shorterRight'\n```\n\n### `SortTwoTuple`\n\n```typescript\nimport { SortTwoTuple } from 'typescript-tuple'\n\ntype Foo = SortTwoTuple\u003c[0, 1], ['a', 'b', 'c', 'd']\u003e // Expect: [[0, 1], ['a', 'b', 'c', 'd']]\nconst foo: Foo = [[0, 1], ['a', 'b', 'c', 'd']]\n\ntype Bar = SortTwoTuple\u003c[0, 1, 2, 3], ['a', 'b']\u003e // Expect: [['a', 'b'], [0, 1, 2, 3]]\nconst bar: Bar = [['a', 'b'], [0, 1, 2, 3]]\n\ntype Baz = SortTwoTuple\u003c[0, 1, 2], ['a', 'b', 'c', 'd']\u003e // Expect: [[0, 1, 2], ['a', 'b', 'c']]\nconst baz: Baz = [[0, 1], 3, ['a', 'b', 'c']]\n\ntype Qux = SortTwoTuple\u003c[0, 1, 2], ['a', 'b', 'c', 'd'], 'EQUAL'\u003e // Expect: 'EQUAL'\nconst qux: Qux = 'EQUAL'\n```\n\n### `ShortestTuple`\n\n```typescript\nimport { ShortestTuple } from 'typescript-tuple'\n\ntype Foo = ShortestTuple\u003c[[0, 1, 2], [false, true], ['a', 'b', 'c', 'd']]\u003e // Expect: [false, true]\nconst foo: Foo = [false, true]\n\ntype Bar = ShortestTuple\u003c[[0, 1, 2], ['a', 'b', 'c'], ...[false, true][]]\u003e // Expect: [false, true]\nconst bar: Bar = [false, true]\n```\n\n### `LongestTuple`\n\n```typescript\nimport { LongestTuple } from 'typescript-tuple'\n\ntype Foo = LongestTuple\u003c[[0, 1, 2, 3], [false, true], ['a']]\u003e // Expect: [0, 1, 2, 3]\nconst foo: Foo = [0, 1, 2, 3]\n\ntype Bar = LongestTuple\u003c[[], [false, true], ...[0, 1, 2][]]\u003e // Expect: [0, 1, 2]\nconst bar: Bar = [0, 1, 2]\n```\n\n### `FilterTuple`\n\n```typescript\nimport { FilterTuple } from 'typescript-tuple'\n\ntype Foo = FilterTuple\u003c[1, '1'], number\u003e // Expect: [1]\nconst foo: Foo = [1]\n\ntype Bar = FilterTuple\u003c[1, '1', null, true], 1 | '1' | true\u003e // Expect: [1, '1', true]\nconst bar: Bar = [1, '1', true]\n```\n\n## License\n\n[MIT](https://git.io/fA2d9) @ [Hoàng Văn Khải](https://github.com/KSXGitHub)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fksxnodemodules%2Ftypescript-tuple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fksxnodemodules%2Ftypescript-tuple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fksxnodemodules%2Ftypescript-tuple/lists"}