\ No newline at end of file
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/about.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/about.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/about.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/about.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part01.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part01.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part01.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part01.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part02.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part02.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part02.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part02.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part03.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part03.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/build-a-db/part03.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/build-a-db/part03.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/building-typescript-node-apps-with-nix.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/building-typescript-node-apps-with-nix.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/building-typescript-node-apps-with-nix.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/building-typescript-node-apps-with-nix.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/efficient-nix-derivations-with-file-sets.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/efficient-nix-derivations-with-file-sets.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/efficient-nix-derivations-with-file-sets.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/efficient-nix-derivations-with-file-sets.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/exposing-a-rust-library-to-node-with-napirs.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/exposing-a-rust-library-to-node-with-napirs.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/exposing-a-rust-library-to-node-with-napirs.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/exposing-a-rust-library-to-node-with-napirs.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/intermediate-typescript-generics-and-mapped-types.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/intermediate-typescript-generics-and-mapped-types.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/intermediate-typescript-generics-and-mapped-types.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/intermediate-typescript-generics-and-mapped-types.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/intermediate-typescript.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/intermediate-typescript.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/intermediate-typescript.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/intermediate-typescript.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/organizing-system-configs-with-nixos.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/organizing-system-configs-with-nixos.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/organizing-system-configs-with-nixos.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/organizing-system-configs-with-nixos.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/1.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/1.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/1.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/1.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/2.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/2.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/2.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/2.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/3.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/3.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/page/3.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/page/3.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/rust-enviorment-and-docker-build-with-nix-flakes.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/rust-enviorment-and-docker-build-with-nix-flakes.json
similarity index 100%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/rust-enviorment-and-docker-build-with-nix-flakes.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/rust-enviorment-and-docker-build-with-nix-flakes.json
diff --git a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/type-safe-groupby-in-typescript.json b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/type-safe-groupby-in-typescript.json
similarity index 88%
rename from _next/data/_FHim0G2RtBJmEIVqQhwr/blog/type-safe-groupby-in-typescript.json
rename to _next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/type-safe-groupby-in-typescript.json
index e643e1d..bf14054 100644
--- a/_next/data/_FHim0G2RtBJmEIVqQhwr/blog/type-safe-groupby-in-typescript.json
+++ b/_next/data/Uq4sBV3BGaoHG9usvVJ-V/blog/type-safe-groupby-in-typescript.json
@@ -1 +1 @@
-{"pageProps":{"post":{"mdxSource":"var Component=(()=>{var i=Object.create;var c=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var a=r=>c(r,\"__esModule\",{value:!0});var m=(r,n)=>()=>(n||r((n={exports:{}}).exports,n),n.exports),u=(r,n)=>{a(r);for(var s in n)c(r,s,{get:n[s],enumerable:!0})},T=(r,n,s)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let l of F(n))!h.call(r,l)&&l!==\"default\"&&c(r,l,{get:()=>n[l],enumerable:!(s=p(n,l))||s.enumerable});return r},v=r=>T(a(c(r!=null?i(y(r)):{},\"default\",r&&r.__esModule&&\"default\"in r?{get:()=>r.default,enumerable:!0}:{value:r,enumerable:!0})),r);var d=m((R,t)=>{t.exports=_jsx_runtime});var f={};u(f,{default:()=>b,frontmatter:()=>K});var e=v(d()),K={title:\"Type Safe GroupBy In TypeScript\",date:\"2022-05-25\",tags:[\"typescript\",\"types\",\"code\",\"guide\"],draft:!1,summary:\"Create a better groupBy function that only allows valid keys to be grouped on\",images:[],layout:\"PostLayout\"};function g(r={}){let{wrapper:n}=r.components||{};return n?(0,e.jsx)(n,Object.assign({},r,{children:(0,e.jsx)(s,{})})):s();function s(){let l=Object.assign({h2:\"h2\",a:\"a\",span:\"span\",p:\"p\",pre:\"pre\",div:\"div\",code:\"code\",\"data-lsp\":\"data-lsp\",em:\"em\",\"data-err\":\"data-err\"},r.components),{TOCInline:o}=l;return o||C(\"TOCInline\",!0),(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(o,{toc:r.toc,asDisclosure:!0}),`\n`,(0,e.jsxs)(l.h2,{id:\"lodashs-groupby\",children:[(0,e.jsx)(l.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#lodashs-groupby\",children:(0,e.jsx)(l.span,{className:\"icon icon-link\"})}),\"Lodash's groupBy\"]}),`\n`,(0,e.jsxs)(l.p,{children:[\"I would bet if you have a sizeable Javascript/Typescript codebase you most likely are using \",(0,e.jsx)(l.a,{href:\"https://lodash.com/\",children:\"lodash\"}),` somewhere in there.\nWhile Javascript has gotten more \"batteries included\" over the last few years, lodash still has many nice functions for manipulating arrays/objects.\nOne such function is `,(0,e.jsx)(l.a,{href:\"https://lodash.com/docs/4.17.15#groupBy\",children:\"groupBy\"}),\". It groups a list by some predicate, in the simplest case it can just be a key in the objects of the array.\"]}),`\n\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"import\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:`(alias) namespace _\n(alias) const _: import(\"/home/runner/work/JRMurr.github.io/JRMurr.github.io/node_modules/@types/lodash/index.d.ts\").LoDashStatic\nimport _`,children:\"_\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"from\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"lodash\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"interface\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Foo\",children:\"Foo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.num: number\",children:\"num\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"number\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'(property) Foo.someLiteral: \"a\" | \"b\" | \"c\"',children:\"someLiteral\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"a\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"|\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"b\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"|\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"c\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Foo\",children:\"Foo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[] \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" { \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.num: number\",children:\"num\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"1\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'(property) Foo.someLiteral: \"a\" | \"b\" | \"c\"',children:\"someLiteral\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"a\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" { \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) key: string\",children:\"key\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"value\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" } },\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" { \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.num: number\",children:\"num\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"2\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'(property) Foo.someLiteral: \"a\" | \"b\" | \"c\"',children:\"someLiteral\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"a\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" { \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) key: string\",children:\"key\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"diffValue\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" } },\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" { \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.num: number\",children:\"num\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"1\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'(property) Foo.someLiteral: \"a\" | \"b\" | \"c\"',children:\"someLiteral\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"b\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\", \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {} },\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"];\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"var console: Console\",children:\"console\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Console.dir(item?: any, options?: any): void\",children:\"dir\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:`(alias) namespace _\n(alias) const _: import(\"/home/runner/work/JRMurr.github.io/JRMurr.github.io/node_modules/@types/lodash/index.d.ts\").LoDashStatic\nimport _`,children:\"_\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) LoDashStatic.groupBy(collection: _.List | null | undefined, iteratee?: _.ValueIteratee | undefined): _.Dictionary (+1 overload)\",children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"num\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"));\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" '1': [ { num: 1, someLiteral: 'a' }, { num: 1, someLiteral: 'b' } ],\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" '2': [ { num: 2, someLiteral: 'a' } ]\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"var console: Console\",children:\"console\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Console.dir(item?: any, options?: any): void\",children:\"dir\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:`(alias) namespace _\n(alias) const _: import(\"/home/runner/work/JRMurr.github.io/JRMurr.github.io/node_modules/@types/lodash/index.d.ts\").LoDashStatic\nimport _`,children:\"_\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) LoDashStatic.groupBy(collection: _.List | null | undefined, iteratee?: _.ValueIteratee | undefined): _.Dictionary (+1 overload)\",children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"someLiteral\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"));\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" a:[\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 1, someLiteral: 'a', object: [Object] },\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 2, someLiteral: 'a', object: [Object] }\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" ],\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" b: [ { num: 1, someLiteral: 'b', object: {} } ]\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})})]})})]}),`\n`,(0,e.jsx)(l.p,{children:\"This all seems to make sense, you can set what key you want to group on, and you get back an object whose keys are the values for found in the input array of objects.\"}),`\n`,(0,e.jsxs)(l.p,{children:[\"Now if you're in a TypeScript code base I hope you are using the \",(0,e.jsx)(l.a,{href:\"https://www.npmjs.com/package/@types/lodash\",children:\"definitely typed lodash types\"}),` to add some types to the lodash functions.\nIn this case the `,(0,e.jsx)(l.code,{children:\"_.groupBy\"}),\" type looks roughly like (simplified from the actual code)\"]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"declare\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function groupBy(collection: Array, key: string): Dictionary\",children:\"groupBy\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy(collection: T[], key: string): Dictionary\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">(\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) collection: T[]\",children:\"collection\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Array\",children:\"Array\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy(collection: T[], key: string): Dictionary\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">, \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: string\",children:\"key\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Dictionary\",children:\"Dictionary\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy(collection: T[], key: string): Dictionary\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]>;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"interface\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Dictionary\",children:\"Dictionary\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in Dictionary\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) index: string\",children:\"index\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"]\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in Dictionary\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"So a few things stick out here. First, the \",(0,e.jsx)(l.code,{children:\"key\"}),\" type is just string, so there's nothing stopping me from doing \",(0,e.jsx)(l.code,{children:'_.groupBy(vals, \"someKeyThatDoesNotExist\")'}),`.\nSecond, we have no restrictions at the type level of me grouping on a key whose value is not a valid object key (the value must be a subset of `,(0,e.jsx)(l.code,{children:\"string | number | symbol\"}),\"). For example in \",(0,e.jsx)(l.code,{children:\"Foo\"}),\" the \",(0,e.jsx)(l.code,{children:\"object\"}),\" key's value was a record. Here's what happens when you try to group on that key.\"]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"var console: Console\",children:\"console\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Console.dir(item?: any, options?: any): void\",children:\"dir\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:`(alias) namespace _\n(alias) const _: import(\"/home/runner/work/JRMurr.github.io/JRMurr.github.io/node_modules/@types/lodash/index.d.ts\").LoDashStatic\nimport _`,children:\"_\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) LoDashStatic.groupBy(collection: _.List | null | undefined, iteratee?: _.ValueIteratee | undefined): _.Dictionary (+1 overload)\",children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"object\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"));\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" '[object Object]': [\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 1, someLiteral: 'a', object: [Object] },\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 2, someLiteral: 'a', object: [Object] },\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 1, someLiteral: 'b', object: {} }\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" ]\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"In this case the objects where coerced to string values so all elements of \",(0,e.jsx)(l.code,{children:\"vals\"}),\" where grouped under the same weird \",(0,e.jsx)(l.code,{children:\"[object Object]\"}),\" key. While this does not throw an error there is almost 0 chance you want this to happen in your code.\"]}),`\n`,(0,e.jsxs)(l.p,{children:[\"Finally, the return type of this function is \",(0,e.jsx)(l.code,{children:\"Dictionary\"}),`, while its \"right\" it could be \"more right\" by encoding that the returning object's keys would be the values of the grouping key in the input object.`]}),`\n`,(0,e.jsxs)(l.h2,{id:\"making-our-own-groupby\",children:[(0,e.jsx)(l.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#making-our-own-groupby\",children:(0,e.jsx)(l.span,{className:\"icon icon-link\"})}),\"Making our own groupBy\"]}),`\n`,(0,e.jsx)(l.p,{children:(0,e.jsx)(l.em,{children:\"insert Bender joke here\"})}),`\n`,(0,e.jsxs)(l.p,{children:[\"To start making our own type safe \",(0,e.jsx)(l.code,{children:\"groupBy\"}),\", we first need some code that actually does the grouping logic. Let's start with that and some basic types.\"]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// Note: PropertyKey is a builtIn type alias of\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// type PropertyKey = string | number | symbol\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:'// This lets us use \"Record\" to represent any object'})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:'// but is slightly nicer to use than the \"object\" type'})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function simpleGroupBy>(arr: T[], key: keyof T): any\",children:\"simpleGroupBy\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in simpleGroupBy>(arr: T[], key: keyof T): any\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">>(\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in simpleGroupBy>(arr: T[], key: keyof T): any\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: keyof T\",children:\"key\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in simpleGroupBy>(arr: T[], key: keyof T): any\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.reduce(callbackfn: (previousValue: any, currentValue: T, currentIndex: number, array: T[]) => any, initialValue: any): any (+2 overloads)\",children:\"reduce\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"((\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: any\",children:\"accumulator\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\") \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=>\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: keyof T\",children:\"key\"}),\"];\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"if\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" (\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"!\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: any\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"}),\"]) {\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: any\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"}),\"] \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [];\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: any\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"}),\"].\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"any\",children:\"push\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\");\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: any\",children:\"accumulator\"}),\";\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }, {} \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"as\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"var console: Console\",children:\"console\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Console.dir(item?: any, options?: any): void\",children:\"dir\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"(\"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function simpleGroupBy(arr: Foo[], key: keyof Foo): any\",children:\"simpleGroupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"num\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"));\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" '1': [\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 1, someLiteral: 'a', object: [Object] },\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" { num: 1, someLiteral: 'b', object: {} }\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" ],\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" '2': [ { num: 2, someLiteral: 'a', object: [Object] } ]\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})})]})})]}),`\n`,(0,e.jsx)(l.p,{children:\"Cool the logic here seems to work, but obviously the types could use some love.\"}),`\n`,(0,e.jsxs)(l.p,{children:[`Let's start by adding a few more generics, so we can type the output correctly.\nYour first change might be to make the return type `,(0,e.jsx)(l.code,{children:\"Record\"}),` since the keys will be coerced to strings by JavaScript and the values will be the same values in the array.\nThis will unfortunately make typescript sad.`]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function sadAttempt(arr: T[], key: keyof T): Record\",children:\"sadAttempt\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in sadAttempt(arr: T[], key: keyof T): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"object\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">(\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in sadAttempt(arr: T[], key: keyof T): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: keyof T\",children:\"key\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in sadAttempt(arr: T[], key: keyof T): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in sadAttempt(arr: T[], key: keyof T): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]> {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.reduce>(callbackfn: (previousValue: Record, currentValue: T, currentIndex: number, array: T[]) => Record, initialValue: Record<...>): Record<...> (+2 overloads)\",children:\"reduce\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"((\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends object\",children:\"val\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\") \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=>\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends object\",children:\"val\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: keyof T\",children:\"key\"}),\"];\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"if\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" (\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"!\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsxs)(l[\"data-err\"],{children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"})]}),\"]) {\"]})]}),(0,e.jsxs)(l.span,{className:\"error\",children:[(0,e.jsx)(l.span,{children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsx)(l.span,{className:\"code\",children:\"2536\"})]}),(0,e.jsx)(l.span,{className:\"error-behind\",children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsxs)(l[\"data-err\"],{children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"})]}),\"] \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [];\"})]}),(0,e.jsxs)(l.span,{className:\"error\",children:[(0,e.jsx)(l.span,{children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsx)(l.span,{className:\"code\",children:\"2536\"})]}),(0,e.jsx)(l.span,{className:\"error-behind\",children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsxs)(l[\"data-err\"],{children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[keyof T]\",children:\"groupedKey\"})]}),\"].\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"any\",children:\"push\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends object\",children:\"val\"}),\");\"]})]}),(0,e.jsxs)(l.span,{className:\"error\",children:[(0,e.jsx)(l.span,{children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsx)(l.span,{className:\"code\",children:\"2536\"})]}),(0,e.jsx)(l.span,{className:\"error-behind\",children:\"Type 'T[keyof T]' cannot be used to index type 'Record'.\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\";\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }, {} \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"as\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in sadAttempt(arr: T[], key: keyof T): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]>);\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"The lines with \",(0,e.jsx)(l.code,{children:\"accumulator[groupedKey]\"}),\" will error with \",(0,e.jsx)(l.code,{children:\"Type 'T[keyof T]' cannot be used to index type 'Record'\"}),\". Here the \",(0,e.jsx)(l.code,{children:\"keyof T\"}),\" could be any key in \",(0,e.jsx)(l.code,{children:\"T\"}),\" so since not every key's value in \",(0,e.jsx)(l.code,{children:\"T\"}),\" is a string typescript will not let you treat \",(0,e.jsx)(l.code,{children:\"groupedKey\"}),\" as a string.\"]}),`\n`,(0,e.jsx)(l.p,{children:\"We can almost fix this by adding some more information on the input key by binding it to a new generic parameter, though there will still be some issues.\"}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"betterSadAttempt\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">, \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">(\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[],\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: Key extends keyof T\",children:\"key\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"Key\"})})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]> {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.reduce>(callbackfn: (previousValue: Record, currentValue: T, currentIndex: number, array: T[]) => Record, initialValue: Record<...>): Record<...> (+2 overloads)\",children:\"reduce\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"((\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\") \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=>\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: Key extends keyof T\",children:\"key\"}),\"];\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"if\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" (\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"!\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"]) {\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"] \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [];\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"].\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.push(...items: T[]): number\",children:\"push\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\");\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\";\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }, {} \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"as\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in betterSadAttempt, Key extends keyof T>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]>);\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"Here we added a new generic \",(0,e.jsx)(l.code,{children:\"Key extends keyof T\"}),\" so when we supply a specific key to the function, the Key generic will be narrowed to that value. For example if we did \",(0,e.jsx)(l.code,{children:\"betterSadAttempt(vals, 'someLiteral')\"}),\", \",(0,e.jsx)(l.code,{children:\"Key\"}),\" would exactly be \",(0,e.jsx)(l.code,{children:\"'someLiteral'\"}),\" instead of \",(0,e.jsx)(l.code,{children:\"keyof Foo = 'someLiteral' | 'num' | 'object'\"})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"However, typescript is still sad on the \",(0,e.jsx)(l.code,{children:\"Record\"}),\" lines with \",(0,e.jsx)(l.code,{children:\"Type 'T[Key]' does not satisfy the constraint 'string | number | symbol'\"}),`.\nThis error is similar to the error before, basically `,(0,e.jsx)(l.code,{children:\"T[Key]\"}),\" can not be a key for the \",(0,e.jsx)(l.code,{children:\"Record\"}),\" since it could be some weird value.\"]}),`\n`,(0,e.jsxs)(l.p,{children:[\"To accomplish this we need to make a helper type that filters down the allowed keys to only keys whose values are \",(0,e.jsx)(l.code,{children:\"string | number | symbol\"}),`.\nWe can use a `,(0,e.jsx)(l.a,{href:\"https://www.typescriptlang.org/docs/handbook/2/mapped-types.html\",children:\"mapped type\"}),\" to do just that\"]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"in\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"]\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"] \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"?\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"never\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"};\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed[keyof T]\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">[\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"];\"})]})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"This type helper does a few things. First it maps over all the values in \",(0,e.jsx)(l.code,{children:\"T\"}),\" (\",(0,e.jsx)(l.code,{children:\"[K in keyof T]\"}),\") and makes the value the key if it is a subset of \",(0,e.jsx)(l.code,{children:\"string | number | symbol\"}),\" (\",(0,e.jsx)(l.code,{children:\"T[K] extends PropertyKey ? K\"}),\"), if it's not a subset its value will be the \",(0,e.jsx)(l.code,{children:\"never\"}),\" type. Finally, we use an \",(0,e.jsx)(l.a,{href:\"https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html\",children:\"index access type\"}),\" to get all values of the transformed object as a union. This step will drop all the \",(0,e.jsx)(l.code,{children:\"never\"}),\" values automatically for us since adding \",(0,e.jsx)(l.code,{children:\"never\"}),\" to a union is like saying \",(0,e.jsx)(l.code,{children:\"or false\"}),\" its basically is a no op.\"]}),`\n`,(0,e.jsx)(l.p,{children:\"That was a mouthful so let's see an example\"}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// from above\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"interface\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Foo\",children:\"Foo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.num: number\",children:\"num\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"number\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'(property) Foo.someLiteral: \"a\" | \"b\" | \"c\"',children:\"someLiteral\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"a\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"|\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"b\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"|\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"c\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) Foo.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:`type MappedFoo = {\n num: \"num\";\n someLiteral: \"someLiteral\";\n object: never;\n}`,children:\"MappedFoo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Foo\",children:\"Foo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:' num: \"num\";'})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:' someLiteral: \"someLiteral\";'})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" object: never;\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// we replace the values of this object with just the key as a string literal or never\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:'type FooKeys = \"num\" | \"someLiteral\"',children:\"FooKeys\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed[keyof T]\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface Foo\",children:\"Foo\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:'// => \"num\" | \"someLiteral\"'})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// notice the never does not show up in the union\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"interface\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface AllObjects\",children:\"AllObjects\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) AllObjects.object: Record\",children:\"object\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"string\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(property) AllObjects.diffObject: Record\",children:\"diffObject\"})]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"number\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:`type MappedAllObjects = {\n object: never;\n diffObject: never;\n}`,children:\"MappedAllObjects\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface AllObjects\",children:\"AllObjects\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"/*\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"{ \"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" object: never;\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\" diffObject: never;\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"*/\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type AllObjectsKeys = never\",children:\"AllObjectsKeys\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed[keyof T]\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"interface AllObjects\",children:\"AllObjects\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// => never\"})}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:'// the output is only never. Think of this like saying \"false or false\", the output will just be false'})})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[\"With this filter type helper function we can now properly limit the \",(0,e.jsx)(l.code,{children:\"Key\"}),\" generic by replacing \",(0,e.jsx)(l.code,{children:\"Key extends keyof T\"}),\" with \",(0,e.jsx)(l.code,{children:\"Key extends Filter\"}),\".\"]}),`\n`,(0,e.jsxs)(l.h2,{id:\"putting-it-all-together\",children:[(0,e.jsx)(l.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#putting-it-all-together\",children:(0,e.jsx)(l.span,{className:\"icon icon-link\"})}),\"Putting it all together\"]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"in\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"]\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type MapValuesToKeysIfAllowed\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"] \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"?\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) K\",children:\"K\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"never\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"};\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed[keyof T]\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">[\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"];\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"groupBy\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"any\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">, \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed[keyof T]\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">>(\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[],\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: Key extends Filter\",children:\"key\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"Key\"})})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]> {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.reduce>(callbackfn: (previousValue: Record, currentValue: T, currentIndex: number, array: T[]) => Record, initialValue: Record<...>): Record<...> (+2 overloads)\",children:\"reduce\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"((\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\") \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=>\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) key: Key extends Filter\",children:\"key\"}),\"];\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"if\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" (\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"!\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"]) {\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"] \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" [];\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }\"})}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\"[\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const groupedKey: T[Key]\",children:\"groupedKey\"}),\"].\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.push(...items: T[]): number\",children:\"push\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) val: T extends Record\",children:\"val\"}),\");\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) accumulator: Record\",children:\"accumulator\"}),\";\"]})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" }, {} \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"as\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Key in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"Key\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupBy, Key extends Filter>(arr: T[], key: Key): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]>);\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"}\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const nums: Record\",children:\"nums\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:'function groupBy(arr: Foo[], key: \"num\"): Record',children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"num\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// nums = Record\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'const literals: Record<\"a\" | \"b\" | \"c\", Foo[]>',children:\"literals\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:'function groupBy(arr: Foo[], key: \"someLiteral\"): Record<\"a\" | \"b\" | \"c\", Foo[]>',children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"someLiteral\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:'// literals = Record<\"a\" | \"b\" | \"c\", Foo[]>'})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'const sad: Record',children:\"sad\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:'function groupBy>(arr: Foo[], key: Filter): Record',children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"object\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsxs)(l.span,{className:\"error\",children:[(0,e.jsx)(l.span,{children:`Argument of type '\"object\"' is not assignable to parameter of type 'Filter'.`}),(0,e.jsx)(l.span,{className:\"code\",children:\"2345\"})]}),(0,e.jsx)(l.span,{className:\"error-behind\",children:`Argument of type '\"object\"' is not assignable to parameter of type 'Filter'.`})]})})]}),`\n`,(0,e.jsxs)(l.p,{children:[`Now this works great, we can only pass in keys that have valid values, and we even get autocomplete on it! However, one thing that bothers me is the error message in the last case.\nWhile it's correct, saying `,(0,e.jsx)(l.code,{children:\"not assignable to parameter of type 'Filter'\"}),\" is not very useful to a user. This pops up sometimes with typescript where it won't show the underlying type and instead just show the higher level type helper instead.\"]}),`\n`,(0,e.jsxs)(l.p,{children:[\"To make the error message show the valid keys we can use a modified version of \",(0,e.jsx)(l.a,{href:\"https://stackoverflow.com/a/57683652\",children:'this \"hack\"'}),\". Here instead of creating the \",(0,e.jsx)(l.code,{children:\"Expand\"}),\" type in the post, we can make our own \",(0,e.jsx)(l.code,{children:\"ValuesOf\"}),\" to replace the \",(0,e.jsx)(l.code,{children:\"[keyof T]\"}),\" at the end of \",(0,e.jsx)(l.code,{children:\"Filter\"})]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type ValuesOf = A extends infer O ? A[keyof A] : never\",children:\"ValuesOf\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) A in type ValuesOf\",children:\"A\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) A in type ValuesOf\",children:\"A\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"infer\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) O\",children:\"O\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"?\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) A in type ValuesOf\",children:\"A\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"keyof\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) A in type ValuesOf\",children:\"A\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"] \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:\"never\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\";\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"type\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Filter = MapValuesToKeysIfAllowed extends infer O ? (O & MapValuesToKeysIfAllowed)[keyof T | keyof O] : never\",children:\"Filter\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"> \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type ValuesOf = A extends infer O ? A[keyof A] : never\",children:\"ValuesOf\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type MapValuesToKeysIfAllowed = { [K in keyof T]: T[K] extends PropertyKey ? K : never; }\",children:\"MapValuesToKeysIfAllowed\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in type Filter\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">>;\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// was Filter = MapValuesToKeysIfAllowed[keyof T]\"})}),(0,e.jsx)(l.div,{className:\"line\",children:\"\\xA0\"}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"const\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:'const sad: Record',children:\"sad\"}),\" \"]}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:'function groupBy(arr: Foo[], key: \"num\" | \"someLiteral\"): Record',children:\"groupBy\"})}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\"(\",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"const vals: Foo[]\",children:\"vals\"}),\", \"]}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F1FA8C\"},children:\"object\"}),(0,e.jsx)(l.span,{style:{color:\"#E9F284\"},children:\"'\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsxs)(l.span,{className:\"error\",children:[(0,e.jsx)(l.span,{children:`Argument of type '\"object\"' is not assignable to parameter of type '\"num\" | \"someLiteral\"'.`}),(0,e.jsx)(l.span,{className:\"code\",children:\"2345\"})]}),(0,e.jsx)(l.span,{className:\"error-behind\",children:`Argument of type '\"object\"' is not assignable to parameter of type '\"num\" | \"someLiteral\"'.`})]})})]}),`\n`,(0,e.jsx)(l.p,{children:\"Now we have type safety and good error messages!\"}),`\n`,(0,e.jsxs)(l.h2,{id:\"possible-improvements\",children:[(0,e.jsx)(l.a,{\"aria-hidden\":\"true\",tabIndex:\"-1\",href:\"#possible-improvements\",children:(0,e.jsx)(l.span,{className:\"icon icon-link\"})}),\"Possible improvements\"]}),`\n`,(0,e.jsxs)(l.p,{children:[\"One thing this \",(0,e.jsx)(l.code,{children:\"groupBy\"}),\" function lacks that the lodash \",(0,e.jsx)(l.code,{children:\"groupBy\"}),` gives is we do not allow you to pass a function instead of a key to group on.\nThe example in the lodash docs is`]}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[(0,e.jsx)(l[\"data-lsp\"],{lsp:`(alias) namespace _\n(alias) const _: import(\"/home/runner/work/JRMurr.github.io/JRMurr.github.io/node_modules/@types/lodash/index.d.ts\").LoDashStatic\nimport _`,children:\"_\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) LoDashStatic.groupBy(collection: _.List | null | undefined, iteratee?: _.ValueIteratee | undefined): _.Dictionary (+1 overload)\",children:\"groupBy\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"([\"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"6.1\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"4.2\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:\"6.3\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"], \"}),(0,e.jsx)(l.span,{style:{color:\"#BD93F9\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"var Math: Math\",children:\"Math\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\".\"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Math.floor(x: number): number\",children:\"floor\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\");\"})]}),(0,e.jsx)(l.div,{className:\"line\",children:(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// { '4': [4.2], '6': [6.1, 6.3] }\"})})]})})]}),`\n`,(0,e.jsx)(l.p,{children:\"While this is not perfect this mostly works\"}),`\n`,(0,e.jsxs)(l.pre,{className:\"shiki dracula twoslash lsp\",style:{backgroundColor:\"#282A36\",color:\"#F8F8F2\"},children:[(0,e.jsx)(l.div,{className:\"language-id\",children:\"ts\"}),(0,e.jsx)(l.div,{className:\"code-container\",children:(0,e.jsxs)(l.code,{children:[(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"function\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"function groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"groupByFunc\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) RetType in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"RetType\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type PropertyKey = string | number | symbol\",children:\"PropertyKey\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\",\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#6272A4\"},children:\"// no longer need any requirements on T since the grouper can do w/e it wants\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Func in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"Func\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"extends\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" (\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arg: T\",children:\"arg\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\") \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"=>\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) RetType in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"RetType\"})})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\">(\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[], \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) mapper: Func extends (arg: T) => RetType\",children:\"mapper\"})}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) Func in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"Func\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\")\"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\":\"}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#8BE9FD\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"type Record = { [P in K]: T; }\",children:\"Record\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"<\"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) RetType in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"RetType\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\", \"}),(0,e.jsx)(l.span,{style:{color:\"#FFB86C\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(type parameter) T in groupByFunc RetType>(arr: T[], mapper: Func): Record\",children:\"T\"})}),(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\"[]> {\"})]}),(0,e.jsxs)(l.div,{className:\"line\",children:[(0,e.jsx)(l.span,{style:{color:\"#F8F8F2\"},children:\" \"}),(0,e.jsx)(l.span,{style:{color:\"#FF79C6\"},children:\"return\"}),(0,e.jsxs)(l.span,{style:{color:\"#F8F8F2\"},children:[\" \",(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(parameter) arr: T[]\",children:\"arr\"}),\".\"]}),(0,e.jsx)(l.span,{style:{color:\"#50FA7B\"},children:(0,e.jsx)(l[\"data-lsp\"],{lsp:\"(method) Array.reduce