1import"../chunks/Bzak7iHL.js";import"../chunks/kfVmCPsV.js";import{p as $a,g as Fa,d as _a,b as Va,f as Ra,s as t,e as s,a as Ta,r as a,n as e}from"../chunks/C2PHntuy.js";import{h as o}from"../chunks/C3QlhiH-.js";import{i as Na}from"../chunks/BQOOHHT8.js";import{l as Ca,s as Ha}from"../chunks/gzNpScmH.js";import{B as Da}from"../chunks/B1caYEk9.js";import{t as ja}from"../chunks/C3bQ3Oc7.js";const As={title:"Extract parameter types from string literal types with TypeScript",description:"Parse and derive types from string literal types in TypeScript using the Template Literal Types, turning `'/purchase/[shopid]/[itemid]/args/[...args]'` into `{ shopid: number, itemid: number, args: string[] }`",date:"2022-03-27T08:00:00Z",tags:["typescript","template literal type","conditional type"],label:"blog",tableOfContents:[{link:"the-challenge",title:"The Challenge"},{link:"things-you-need-to-know",title:"Things you need to know",nested:[{link:"string-literal-type",title:"String Literal Type",nested:[{link:"template-literal-and-string-literal-types",title:"Template Literal and String Literal Types"}]},{link:"conditional-type",title:"Conditional Type"},{link:"function-overloads-and-generic-functions",title:"Function Overloads and Generic Functions"}]},{link:"working-on-the-problem",title:"Working on the problem",nested:[{link:"the-game-plan",title:"The Game Plan"},{link:"splitting-a-string-literal-type",title:"Splitting a String Literal Type"},{link:"filter-out-only-the-parts-containing-the-param-syntax",title:"Filter out only the parts containing the param syntax"},{link:"removing-the-brackets",title:"Removing the brackets"},{link:"map-the-parts-into-an-object-type",title:"Map the parts into an Object Type"},{link:"defining-the-map-value",title:"Defining the map value"},{link:"remap-keys-to-remove",title:"Remap keys to remove `'...'`"},{link:"the-solution",title:"The Solution"}]},{link:"conclusion",title:"Conclusion"},{link:"extra",title:"Extra"},{link:"references",title:"References"}]},{title:Qa,description:Ua,date:Ya,tags:Za,label:st,tableOfContents:at}=As;var Ea=Va(`<section><h2><a href="#the-challenge" id="the-challenge">The Challenge</a></h2> <p>First of all, here's a TypeScript challenge for you:</p> <p>Can you figure how to define the TypeScript type for the <code class="inline">app.get</code> method below?</p> <div class="code-section"><!></div> <p><em>Try and hover the variables to look at their types.</em></p> <p><em>Notice that <code class="inline">...args</code> is a string array instead of number</em> ð¤¯</p> <p>The <code class="inline">req.params</code> is derived from the string passed in as the 1st parameter.</p> <p>
1This is useful when you want to define types for a routing-like function, where you can pass in a route with path pattern that you can define dynamic segments with custom syntax (eg: <code class="inline">[shopid]</code> or <code class="inline">:shopid</code>), and a callback function, where the argument type is derived from the route that you just passed in.</p> <p>So if you try to access parameter that is not defined, you get an error!</p> <div class="code-section"><!></div> <p>A real-world use-case for this, if you are more familiar with <a href="https://v5.reactrouter.com/" rel="nofollow">React Router</a>, is to derive the type for <code class="inline">routeProps</code> in the <a href="https://v5.reactrouter.com/web/api/Route/render-func" rel="nofollow">render</a> function from the <code class="inline">path</code> props:</p> <div class="code-section"><!></div> <p>In this article, we are going to explore how to define such a type, through various TypeScript techniques, extracting types from a string literal type.</p></section> <section><h2><a href="#things-you-need-to-know" id="things-you-need-to-know">Things you need to know</a></h2> <p>First thing first, let's talk through some basic knowledges required before we go on and tackle the problem.</p></section> <section><h3><a href="#string-literal-type" id="string-literal-type">String Literal Type</a></h3> <p>Type <code class="inline">string</code> in TypeScript is a string that can have any value:</p> <div class="code-section"><!></div> <p>However, a <a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types" rel="nofollow">string literal type</a>, is a string type with a specific value:</p> <div class="code-section"><!></div> <p>Most of the time, we use this alongside with <a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types" rel="nofollow">Union Types</a> to determine a list of string values you can pass to a function / array / object:</p> <div class="code-section"><!></div> <p>So how do you create a string literal type?</p> <p>When you define a string variable with <code class="inline">const</code>, it is of type string literal. However if you defined it with <code class="inline">let</code>, TypeScript sees that the value of the variable could change, so it assigns the variable to a more generic type:</p> <div class="code-section"><!></div> <p>The same reasoning applies to objects and arrays, as you can mutate the object / array value afterwards, so TypeScript assigns a more generic type:</p> <div class="code-section"><!></div> <p>However, you can hint TypeScript that you would only read the value from the object / array and not mutate it, by using the <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions" rel="nofollow"><code class="inline">const</code> assertions</a></p> <div class="code-section"><!></div> <p>Hover over to the <code class="inline">object.food</code> property and you'll see that now the type is a string literal <code class="inline">'sushi'</code> rather than <code class="inline">string</code>!</p> <p>Differentiating a string literal type vs a string type allows TypeScript to know not just the type, as well the value of a string.</p></section> <section><h4><a href="#template-literal-and-string-literal-types" id="template-literal-and-string-literal-types">Template Literal and String Literal Types</a></h4> <p>Since <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#template-literal-types" rel="nofollow">TypeScript 4.1</a>, TypeScript supports a new way to define a new string literal types, which is to use the familiar syntax of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals" rel="nofollow">Template literals</a>:</p> <div class="code-section"><!></div></section> <section><h3><a href="#conditional-type" id="conditional-type">Conditional Type</a></h3> <p><a href="https://www.typescriptlang.org/docs/handbook/2/conditional-types.html" rel="nofollow">Conditional Types</a> allow you to define a type based on another type. In this example, <code class="inline">Collection<X></code> can be either <code class="inline">number[]</code> or <code class="inline">Set<number></code> depending on the type of <code class="inline">X</code>:</p> <div class="code-section"><!></div> <p>You use the <code class="inline">extends</code> keyword to test if the type <code class="inline">X</code> can be assigned to the type <code class="inline">'arr'</code>, and conditional operator (<code class="inline">condition ? a : b</code>) to determine the type if it test holds true or otherwise.</p> <p>If you try to test a more complex type, you can infer parts of the type using the <code class="inline">infer</code> keyword, and define a new type based on the inferred part:</p> <div class="code-section"><!></div></section> <section><h3><a href="#function-overloads-and-generic-functions" id="function-overloads-and-generic-functions">Function Overloads and Generic Functions</a></h3> <p>Whenever you want to define the type of a function in TypeScript, where the argument types and the return type depends on each other, you'll probably will reach out for either <a href="https://www.t
1ypescriptlang.org/docs/handbook/2/functions.html#function-overloads" rel="nofollow">Function Overloads</a> or <a href="https://www.typescriptlang.org/docs/handbook/2/functions.html#generic-functions" rel="nofollow">Generic Functions</a>.</p> <p>What do I meant by having the argument types and return types depending on each other?</p> <p>Here's an example where the return type is based on the argument type:</p> <div class="code-section"><!></div> <p>... and here's another example where the 2nd argument type is based on the 1st argument type (argument types depending on each other):</p> <div class="code-section"><!></div> <p>So, how do you define a function like this?</p> <p>If you define</p> <div class="code-section"><!></div> <p>then whatever returned is type <code class="inline">string | number</code>. This doesnt capture the essence of the function, which should return <code class="inline">string</code> if called the function with <code class="inline">string[]</code> and return <code class="inline">number</code> if you called with <code class="inline">number[]</code>.</p> <p>Instead, you can define the function via <a href="https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads" rel="nofollow">function overloads</a>, which is to define multiple function signatures, followed by the implementation:</p> <div class="code-section"><!></div> <p>Alternatively, you can define a <a href="https://www.typescriptlang.org/docs/handbook/2/functions.html#generic-functions" rel="nofollow">generic function</a>, which declares a <em>type parameter</em>, and describe the argument type and return type in terms of the <em>type parameter</em>:</p> <div class="code-section"><!></div> <p>A plus point for generics is that the <code class="inline">Item</code> type can be any types, and TypeScript can infer what the <code class="inline">Item</code> type represents from the arguments you called the function with, and dictates what the return type should be based on the <code class="inline">Item</code> type</p> <div class="code-section"><!></div> <p>If you do it with function overload, on the other hand, you'll probably have to define each and every possible function signatures.</p> <p>But maybe you just want to pass in <code class="inline">string[]</code> or <code class="inline">number[]</code> to <code class="inline">firstElement(...)</code> only, so it's not a problem for function overloads.</p> <p>Also, you can provide a constraint for the generic function, limiting that the <code class="inline">Item</code> type parameter can only be a certain type, by using the <code class="inline">extends</code> keyword:</p> <div class="code-section"><!></div></section> <section><h2><a href="#working-on-the-problem" id="working-on-the-problem">Working on the problem</a></h2> <p>Knowing <a href="#function-overloads-and-generic-functions">generic functions</a>, our solution to the problem will probably take the form:</p> <div class="code-section"><!></div> <p>We use a type parameter <code class="inline">Path</code>, which has to be a <code class="inline">string</code>. The <code class="inline">path</code> argument is of type <code class="inline">Path</code> and the callback will be <code class="inline">CallbackFn<Path></code>, and the crux of the challenge is to figure out <code class="inline">CallbackFn<Path></code>.</p></section> <section><h3><a href="#the-game-plan" id="the-game-plan">The Game Plan</a></h3> <p>So here's the plan:</p> <ol start="0"><li>Given the type of the path as <code class="inline">Path</code>, which is a <a href="#string-literal-type">string literal type</a>,</li></ol> <div class="code-section"><!></div> <ol><li>We derive a new type which has the string break into it's parts <em>[<a href="#splitting-a-string-literal-type">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="2"><li>Filter out the parts to contain only the params <em>[<a href="#filter-out-only-the-parts-containing-the-param-syntax">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="3"><li>Remove the brackets <em>[<a href="#removing-the-brackets">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="4"><li>
1Map the parts into an <a href="https://www.typescriptlang.org/docs/handbook/2/objects.html" rel="nofollow">object type</a> <em>[<a href="#map-the-parts-into-an-object-type">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="5"><li>Using <a href="https://www.typescriptlang.org/docs/handbook/2/conditional-types.html" rel="nofollow">Conditional Types</a> to define the map value <em>[<a href="#defining-the-map-value">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="6"><li>Remap keys to remove <code class="inline">'...'</code> in <code class="inline">...args</code> <em>[<a href="#remap-keys-to-remove">jump here</a>]</em></li></ol> <div class="code-section"><!></div> <ol start="7"><li>Finally</li></ol> <div class="code-section"><!></div></section> <section><h3><a href="#splitting-a-string-literal-type" id="splitting-a-string-literal-type">Splitting a String Literal Type</a></h3> <p>To split a string literal type, we can use a <a href="#conditional-type">conditional type</a> to check the value of the string literal:</p> <div class="code-section"><!></div> <p>but to take in any string literal, that we have no idea of the value ahead of time,</p> <div class="code-section"><!></div> <p>we will have to <code class="inline">infer</code> the value in the conditional tests, and use the inferred value type:</p> <div class="code-section"><!></div> <p>And if you pass in a string literal that does not match the pattern, we want to return the same string literal type passed in. 2So, we return the <code class="inline">Path</code> type in the <code class="inline">false</code> condition branch:</p> <div class="code-section"><!></div> <p>At this point, you noticed that <code class="inline">PartA</code> will infer "non-greedily", ie: it will try to infer as much as possible, but do not contain a <code class="inline">"/"</code> character:</p> <div class="code-section"><!></div> <p>So, to split the <code class="inline">Path</code> string literal recursively, we can return the type <code class="inline">Parts<PathB></code> instead of <code class="inline">PathB</code>:</p> <div class="code-section"><!></div> <p>Here's the breakdown of what happened:</p> <div class="code-section"><!></div></section> <section><h3><a href="#filter-out-only-the-parts-containing-the-param-syntax" id="filter-out-only-the-parts-containing-the-param-syntax">Filter out only the parts containing the param syntax</a></h3> <p>The key to this step is the observation that <strong>any type <a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types" rel="nofollow">unions</a> with <code class="inline">never</code> yields the type itself</strong>.</p> <div class="code-section"><!></div> <p>If we can transform</p> <div class="code-section"><!></div> <p>into</p> <div class="code-section"><!></div> <p>then we will have</p> <div class="code-section"><!></div> <p>So, how, you asked?</p> <p>Well, we'll have to reach out to <a href="#conditional-type">conditional types</a> again for help, we can have a conditional type that returns the string literal itself if it starts with <code class="inline">[</code> and ends with <code class="inline">]</code>, and <code class="inline">never</code> if otherwise:</p> <div class="code-section"><!></div> <p>Although we have no idea what the string content is in between <code class="inline">[]</code>, but we can infer it in the conditional type, and we do not have to use the inferred type.</p> <p>Combining this with the previous step, we have:</p> <div class="code-section"><!></div></section> <section><h3><a href="#removing-the-brackets" id="removing-the-brackets">Removing the brackets</a></h3> <p>If you've been following along until this point, you probably have a clearer idea on how we can achieve this step.</p> <p>So, why not take a pause and <a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAkgzgBQIYCckFsLAigPMlYAPigF4oDgoIAPbAOwBM4oADAbQBIBvAS3oBmOKAEF6IYAAt+AcwC+AXVZQA-BVRUAXFHoQAbjgDcAWABQoSFABivADbYUERpTj4kUkuWRTqdCExZWHn4hFHVCETkAemDBYUoAITlWMyhVWERUDCwcNwiSAB9rOwcnFzzgBKJUqG14AmyHNw8TUzMLaAb0OAB1XikAewBXSrQAYwBrLDJi+xwyjVcAciiwIZQxySQ4CCj2OEkBsF5GBT3+iHQTs9QZOD2AOifbuAUlokMgA" rel="nofollow">try it out in the TypeScript Playground</a>? <em>(I've added the boilerplate code in the link)</em></p> <p>To remove the bracket, we can modify the conditional type in the last step, and instead of returning the <code class="inline">Part</code>, we return the inferred type between the <code class="inline">[]</code></p> <div class="code-section"><!></div></section> <section><h3><a href="#map-the-parts-into-an-object-type" id="map-the-parts-into-an-object-type">Map the parts into an Object Type</a></h3> <p>
2In this step, we are going to create an <a href="https://www.typescriptlang.org/docs/handbook/2/objects.html" rel="nofollow">Object Types</a> using the result of the previous step as the key.</p> <p>If you know the key type beforehand, you can create an object type via a type alias:</p> <div class="code-section"><!></div> <p>If the key type is totally unknown, you can use the <a href="https://dmitripavlutin.com/typescript-index-signatures/" rel="nofollow">Index Signature</a>:</p> <div class="code-section"><!></div> <p>However, in our case, the key type is not totally unknown, but it is dynamic. We use <a href="https://www.typescriptlang.org/docs/handbook/2/mapped-types.html" rel="nofollow">Mapped Types</a> which has a similar syntax as the index signature:</p> <div class="code-section"><!></div> <p>Building this on top of the previous step, we have:</p> <div class="code-section"><!></div></section> <section><h3><a href="#defining-the-map-value" id="defining-the-map-value">Defining the map value</a></h3> <p>Now if I ask you to come up with a type that is depending on the key value:</p> <ul><li>if it is a string literal type that starts with <code class="inline">...</code>, <strong>return a type <code class="inline">string[]</code></strong></li> <li>else, <strong>return a type <code class="inline">number</code></strong></li></ul> <p>I hope that your inner voice is shouting <a href="#conditional-type">Conditional Types</a>!</p> <p>And yes, we are going to use a Conditional Type:</p> <div class="code-section"><!></div> <p>But how do we get the <code class="inline">Key</code> type?</p> <p>Well, in Mapped Types, when you write <code class="inline">{ [Key in ???]: any }</code>, the <code class="inline">Key</code> is the type alias of the key, which you can map it in the value type.</p> <p>So writing this:</p> <div class="code-section"><!></div> <p>is the same as doing</p> <div class="code-section"><!></div> <p>So, adding this on top of the previous step:</p> <div class="code-section"><!></div></section> <section><h3><a href="#remap-keys-to-remove" id="remap-keys-to-remove">Remap keys to remove <code class="inline">'...'</code></a></h3> <p>Now the final step. We are going to remove <code class="inline">'...'</code> from the <code class="inline">'...args'</code> key, and I hope you can now proudly come up with the <a href="#conditional-type">Conditional Types</a> for it:</p> <div class="code-section"><!></div> <p>But to apply this onto our Mapped Type, you can do a <a href="https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as" rel="nofollow">Key Remapping via <code class="inline">as</code></a>, which is available from TypeScript 4.1</p> <div class="code-section"><!></div> <p>And there you go!</p></section> <section><h3><a href="#the-solution" id="the-solution">The Solution</a></h3> <p>Here's the final solution to <a href="#the-challenge">the challenge</a>:</p> <div class="code-section"><!></div></section> <section><h2><a href="#conclusion" id="conclusion">Conclusion</a></h2> <p>I hope this is a fun challenge for you.</p> <p>As you can see, there's endless possibilities with <a href="#conditional-type">Conditional Types</a> and <a href="#template-literal-and-string-literal-types">Template Literal Types</a>, allowing you to parse and derive types from a string literal type.</p> <p>Before you go, here's another challenge, see if you can come up with the type for <code class="inline">Parse<Str></code>:</p> <div class="code-section"><!></div> <p>And you just wanna see the answer, <a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAchDOwIBMDKwBOBLAdgcwEEMMBDEKAXiiNJAB5Ft8oAfWBJNTXQ4sgPgDcAWABQoSFFQBrLGFRgSAYwh10GKBAAeSHMnhRGPfpSmZNOiHoMADKABIA3rgBmEDeoC+dgPxTZ8ooqapgmAFxmGCKiYhLQAAokGPAQ6iEa2rr6htz4JlRiUJEWWbYARE6u7lAAaiQANgCuEJ4VzjhuGgBKEAC2JLg83oVFUH4A2jJyCsqqPf2DeQA0tQ3NALojRRGTmCuNehAuuCjr0bHgCUkpAJJIveklVtlGeZQjicmpmOkmmc8GcZVbp9AY4HgrYGrJoQTaiUZjaHNJ7WHJMPBbUYTeZgiFI2GY7ZQT4pdQ8GhkX4o7JAjrVHGLPCQukaOowuEIhF+NnI-6ouCIFBk-AUkCEznY0GMlY8gnwzkInYM8H4faHY44U7ionjZV4g7II4nZAc0Y7dRqw0a07ncSXYnXCB3PrwR58l65JlQHrwRr1YDUgwCzjC3i0fIfR3Oh7qP6WVG0zreqUqr1Q2WmorctbQd1BjhCz2i8YABkzWOTC1TgagNiWlRZldx+GG8oVfhJTvurqmgVmdD1yyg4wAdGOfX7gDKc+t+NqoEqU3jR+OEJPp+zyzrB16J-7y+a9lADUbNSaxBdJJ3Q6K3fGPeiVnuA3n2IKuOjRaZxrPTCN1DWNjjA2SZeDYmIdlG3ZqAEMzBLGT5rv6calMOUI7sySbPluiI7oB6wgfSS4tuBbYSsOGHJr6+7zouVb6uqxo4YeGCWqeWpkSxbHWia0RxA6Xx3qhrx4PkUCRl8N58PQsY1omRH0aqUDoUhwDln4eGvgA5Fp4oaap4oRJqABu7iYkZECmVEF52pIACivRgKAX5UJ2dBaT+WlCGIAD0PmjAAej4l7QFJtCmG5HllAAFhA9T1AA9mUKxlAA7glGD1MgZTrF5vn+UUQUhW+nAuQJKTueMMVxYlyXDmlGVZXVZTAPAdVVQAhDl6wrFVmDkMA0VYG16y5XOoh+YFPhAA" rel="nofollow">here's the link to it</a></p></section> <section><h2><a href="#extra" id="extra">Extra</a></h2> <p>Here's the type I defined for the <code class="inline">Route</code> component in the example above</p> <div class="code-section"><!></div></section> <section><h2><a href="#references" id="references">References</a></h2> <ul><li>TypeScript Docs <ul><li>
2<a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types" rel="nofollow">Literal Types</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types" rel="nofollow">Union Types</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/conditional-types.html" rel="nofollow">Conditional Types</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads" rel="nofollow">Function Overloads</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/functions.html#generic-functions" rel="nofollow">Generic Functions</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/objects.html" rel="nofollow">Objects</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/mapped-types.html" rel="nofollow">Mapped Types</a></li> <li><a href="https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html" rel="nofollow">Template Literal Types</a></li></ul></li> <li><a href="https://mariusschulz.com/blog/string-literal-types-in-typescript" rel="nofollow">String Literal Types in TypeScript</a></li> <li><a href="https://dmitripavlutin.com/typescript-index-signatures/" rel="nofollow">Index Signatures in TypeScript</a></li> <li><a href="https://github.com/DefinitelyTyped/DefinitelyTyped/pull/51262" rel="nofollow">PR in DefinitelyTyped: infering route parameters using template literal types</a></li></ul></section>`,1);function tt(Is,rs){const Ks=Ca(rs,["children","$$slots","$$events","$$legacy"]);$a(rs,!1),Fa("blog",{image:ja}),Na(),Da(Is,Ha(()=>Ks,()=>As,{children:(Bs,Oa)=>{var ns=Ea(),r=Ra(ns),n=t(s(r),6),Ss=s(n);o(Ss,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="1"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const app: { get<Path extends string>(path: Path, fn: (req: { params: { [Key in PathSegments<Path> as Strip<Key>]: Value<Key>; }; }) => void): void; }' >app</data-lsp></span><span style="color: var(--shiki-token-function)">.<data-lsp lsp='(method) get<"/purchase/[shopid]/[itemid]/args/[...args]">(path: "/purchase/[shopid]/[itemid]/args/[...args]", fn: (req: { params: { shopid: number; itemid: number; args: string[]; }; }) => void): void' >get</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) req: { params: { shopid: number; itemid: number; args: string[]; }; }' >req</data-lsp>) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const params: { shopid: number; itemid: number; args: string[]; }' style='border-bottom: solid 2px lightgrey;'>params</data-lsp></span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) req: { params: { shopid: number; itemid: number; args: string[]; }; }' >req</data-lsp>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const params: { 3 shopid: number; 4 itemid: number; 5 args: string[]; 6}</span></div><div class='line'><span style="color: var(--shiki-color-text)">});</span></div><div class='line'><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const app: { get<Path extends string>(path: Path, fn: (req: { params: { [Key in PathSegments<Path> as Strip<Key>]: Value<Key>; }; }
6) => void): void; }' >app</data-lsp></span><span style="color: var(--shiki-token-function)">.<data-lsp lsp='(method) get<"/docs/[chapter]/[section]">(path: "/docs/[chapter]/[section]", fn: (req: { params: { chapter: number; section: number; }; }) => void): void' >get</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'/docs/[chapter]/[section]'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) req: { params: { chapter: number; section: number; }; }' >req</data-lsp>) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const params: { chapter: number; section: number; }' style='border-bottom: solid 2px lightgrey;'>params</data-lsp></span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) req: { params: { chapter: number; section: number; }; }' >req</data-lsp>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const params: { 7 chapter: number; 8 section: number; 9}</span></div><div class='line'><span style="color: var(--shiki-color-text)">});</span></div></code></div></pre>`),a(n);var l=t(n,12),$s=s(l);o($s,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="1"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const app: { get<Path extends string>(path: Path, fn: (req: { params: { [Key in PathSegments<Path> as Strip<Key>]: Value<Key>; }; }) => void): void; }' >app</data-lsp></span><span style="color: var(--shiki-token-function)">.<data-lsp lsp='(method) get<"/purchase/[shopid]/[itemid]/args/[...args]">(path: "/purchase/[shopid]/[itemid]/args/[...args]", fn: (req: { params: { shopid: number; itemid: number; args: string[]; }; }) => void): void' >get</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) req: { params: { shopid: number; itemid: number; args: string[]; }; }' >req</data-lsp>) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)"><data-err><data-lsp lsp='const foo: any' >foo</data-lsp></data-err></span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) req: { params: { shopid: number; itemid: number; args: string[]; }; }' >req</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='(property) params: { shopid: number; itemid: number; args: string[]; }' >params</data-lsp>;</span></div><span class="error"><span>Property 'foo' does not exist on type '{ shopid: number; itemid: number; args: string[]; }'.</span><span class="code">2339</span></span><span class="error-behind">Property 'foo' does not exist on type '{ shopid: number; itemid: number; args: string[]; }'.</span><div class='line'><span style="color: var(--shiki-color-text)">});</span></div></code></div></pre>`),a(l);var ls=t(l,4),Fs=s(ls);o(Fs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="tsx" cutLines="10"><div class="language-id">tsx</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='function Route<"/user/:username">({}: { path: "/user/:username"; render: (routeProps: { match: { params: { username: string; }; }; }
9) => void; }): React.JSX.Element' >Route</data-lsp></span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(property) path: "/user/:username"' >path</data-lsp></span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"/user/:username"</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(property) render: (routeProps: { match: { params: { username: string; }; }; }) => void' >render</data-lsp></span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)">{(<data-lsp lsp='(parameter) routeProps: { match: { params: { username: string; }; }; }' >routeProps</data-lsp>) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const params: { username: string; }' style='border-bottom: solid 2px lightgrey;'>params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) routeProps: { match: { params: { username: string; }; }; }' >routeProps</data-lsp></span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(property) match: { params: { username: string; }; }' >match</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='(property) params: { username: string; }' >params</data-lsp>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const params: { 10 username: string; 11}</span></div><div class='line'><span style="color: var(--shiki-color-text)"> }}</span></div><div class='line'><span style="color: var(--shiki-color-text)">/>;</span></div></code></div></pre>`),a(ls),e(2),a(r);var i=t(r,4),p=t(s(i),4),_s=s(p);o(_s,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='let str: string' >str</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'abc'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)"><data-lsp lsp='let str: string' >str</data-lsp> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'def'</span><span style="color: var(--shiki-color-text)">; </span><span style="color: var(--shiki-token-comment)">// no errors, string type can have any value</span></div></code></div></pre>`),a(p);var c=t(p,4),Vs=s(c);o(Vs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='let str: "abc"' >str</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'abc'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'abc'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)"><data-err><data-lsp lsp='let str: "abc"' >str</data-lsp></data-err> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'def'</span><span style="color: var(--shiki-color-text)">;</span></div><span class="error"><span>Type '"def"' is not assignable to type '"abc"'.</span><span class="code">2322</span></span><span class="error-behind">Type '"def"' is not assignable to type '"abc"'.</span></code></div></pre>`),a(c);var k=t(c,4),Rs=s(k);o(Rs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function eatSomething(food: "sushi" | "ramen"): void' >eatSomething</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) food: "sushi" | "ramen"' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'ramen'</span><span style="color: var(--shiki-color-text)">) {}</span></div><div class='line'><span style="color: var(--shiki-token-function)"><data-lsp lsp='function eatSomething(food: "sushi" | "ramen"): void' >eatSomething</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)">);</span></div><div class='line'><span style="color: var(--shiki-token-function)"><data-lsp lsp='function eatSomething(food: "sushi" | "ramen"): void' >eatSomething</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'ramen'</span><span style="color: var(--shiki-color-text)">);</span></div><div class='line'><span style="color: var(--shiki-token-function)"><data-lsp lsp='function eatSomething(food: "sushi" | "ramen"): void' >eatSomething</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)"><data-err>'pencil'</data-err></span><span style="color: var(--shiki-color-text)">);</span></div><span class="error"><span>Argument of type '"pencil"' is not assignable to parameter of type '"sushi" | "ramen"'.</span><span class="code">2345</span></span><span class="error-behind">Argument of type '"pencil"' is not assignable to parameter of type '"sushi" | "ramen"'.</span><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='let food: ("sushi" | "ramen")[]' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='interface Array<T>' >Array</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'ramen'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)">];
11</span></div><div class='line'><span style="color: var(--shiki-token-constant)"><data-lsp lsp='let food: ("sushi" | "ramen")[]' >food</data-lsp></span><span style="color: var(--shiki-token-function)">.<data-lsp lsp='(method) Array<"sushi" | "ramen">.push(...items: ("sushi" | "ramen")[]): number' >push</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)"><data-err>'pencil'</data-err></span><span style="color: var(--shiki-color-text)">);</span></div><span class="error"><span>Argument of type '"pencil"' is not assignable to parameter of type '"sushi" | "ramen"'.</span><span class="code">2345</span></span><span class="error-behind">Argument of type '"pencil"' is not assignable to parameter of type '"sushi" | "ramen"'.</span><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='let object: { food: "sushi" | "ramen"; }' >object</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) food: "sushi" | "ramen"' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'ramen'</span><span style="color: var(--shiki-color-text)"> };</span></div><div class='line'><span style="color: var(--shiki-color-text)"><data-lsp lsp='let object: { food: "sushi" | "ramen"; }' >object</data-lsp> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) food: "sushi" | "ramen"' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> };</span></div><div class='line'><span style="color: var(--shiki-color-text)"><data-lsp lsp='let object: { food: "sushi" | "ramen"; }' >object</data-lsp> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-err><data-lsp lsp='(property) food: "sushi" | "ramen"' >food</data-lsp></data-err></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'pencil'</span><span style="color: var(--shiki-color-text)"> };</span></div><span class="error"><span>Type '"pencil"' is not assignable to type '"sushi" | "ramen"'.</span><span class="code">2322</span></span><span class="error-behind">Type '"pencil"' is not assignable to type '"sushi" | "ramen"'.</span></code></div></pre>`),a(k);var y=t(k,6),Ts=s(y);o(Ts,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const food: "sushi"' style='border-bottom: solid 2px lightgrey;'>food</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const food: "sushi"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='let drinks: string' style='border-bottom: solid 2px lightgrey;'>drinks</data-lsp> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'beer'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>let drinks: string</span></div></code></div></pre>`),a(y);var d=t(y,4),Ns=s(d);o(Ns,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const object: { food: string; }' style='border-bottom: solid 2px lightgrey;'>object</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) food: string' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> };</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const object: { 12 food: string; 13}</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const array: string[]' style='border-bottom: solid 2px lightgrey;'>array</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)">];
13</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const array: string[]</span></div></code></div></pre>`),a(d);var is=t(d,4),Cs=s(is);o(Cs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const object: { readonly food: "sushi"; }' style='border-bottom: solid 2px lightgrey;'>object</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) food: "sushi"' >food</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)"><data-lsp lsp='type const = { readonly food: "sushi"; }' >const</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const object: { 14 readonly food: "sushi"; 15}</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const array: readonly ["sushi"]' style='border-bottom: solid 2px lightgrey;'>array</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-string-expression)">'sushi'</span><span style="color: var(--shiki-color-text)">] </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)"><data-lsp lsp='type const = readonly ["sushi"]' >const</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const array: readonly ["sushi"]</span></div></code></div></pre>`),a(is),e(4),a(i);var v=t(i,2),ps=t(s(v),4),Hs=s(ps);o(Hs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const a: "a"' >a</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const b: "b"' >b</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// In JavaScript, you can build a new string</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// with template literals</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const c: "a b"' >c</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-color-text)"><data-lsp lsp='const a: "a"' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)"> </span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-color-text)"><data-lsp lsp='const b: "b"' >b</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)">; </span><span style="color: var(--shiki-token-comment)">// 'a b'</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = "a"' >A</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type B = "b"' >B</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// In TypeScript, you can build a new string literal type</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// with template literals too!</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type C = "a b"' style='border-bottom: solid 2px lightgrey;'>C</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = "a"' >A</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)"> </span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type B = "b"' >B</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type C = "a b"</span></div></code></div></pre>`),a(ps),a(v);var h=t(v,2),x=t(s(h),4),Ds=s(x);o(Ds,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Collection<X> = X extends "arr" ? number[] : Set<number>' >Collection</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) X in type Collection<X>' >X</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) X in type Collection<X>' >X</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'arr'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='interface Set<T>' >Set</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = number[]' style='border-bottom: solid 2px lightgrey;'>A</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Collection<X> = X extends "arr" ? number[] : Set<number>' >Collection</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'arr'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type A = number[]</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// If you pass in something other than 'arr'</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type B = Set<number>' style='border-bottom: solid 2px lightgrey;'>B</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Collection<X> = X extends "arr" ? number[] : Set<number>' >Collection</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'foo'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type B = Set<number></span></div></code></div></pre>`),a(x);var cs=t(x,6),js=s(cs);o(js,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-comment)">// Here you are testing whether X extends `() => ???`</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// and let TypeScript to infer the `???`
15 part</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// TypeScript will define a new type called</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// `Value` for the inferred type</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type GetReturnValue<X> = X extends () => infer Value ? Value : never' >GetReturnValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) X in type GetReturnValue<X>' >X</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) X in type GetReturnValue<X>' >X</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> () </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Value' >Value</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Value' >Value</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-comment)">// Here we inferred that `Value` is type `string`</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = string' style='border-bottom: solid 2px lightgrey;'>A</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type GetReturnValue<X> = X extends () => infer Value ? Value : never' >GetReturnValue</data-lsp></span><span style="color: var(--shiki-color-text)"><() </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type A = string</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-comment)">// Here we inferred that `Value` is type `number`</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type B = number' style='border-bottom: solid 2px lightgrey;'>B</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type GetReturnValue<X> = X extends () => infer Value ? Value : never' >GetReturnValue</data-lsp></span><span style="color: var(--shiki-color-text)"><
15() </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type B = number</span></div></code></div></pre>`),a(cs),a(h);var m=t(h,2),g=t(s(m),8),Es=s(g);o(Es,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="2"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<Type>(arr: Type[]): Type | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) arr: any' >arr</data-lsp>) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) arr: any' >arr</data-lsp>[</span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">];</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const string: string | undefined' >string</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<string>(arr: string[]): string | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([</span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'c'</span><span style="color: var(--shiki-color-text)">]);</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const number: number | undefined' >number</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<number>(arr: number[]): number | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([</span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-color-text)">]);</span></div></code></div></pre>`),a(g);var u=t(g,4),Os=s(u);o(Os,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="7"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function calculate<Op extends string>(operation: Op, data: Data<Op>): number | undefined' >calculate</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) operation: any' >operation</data-lsp></span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) data: any' >data</data-lsp>) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) operation: any' >operation</data-lsp> </span><span style="color: var(--shiki-token-keyword)">===</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'add'</span><span style="color: var(--shiki-color-text)">) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) data: any' >data</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='any' >addend_1</data-lsp> </span><span style="color: var(--shiki-token-keyword)">+</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) data: any' >data</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='any' >addend_2</data-lsp>;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">else</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) operation: any' >operation</data-lsp> </span><span style="color: var(--shiki-token-keyword)">===</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'divide'</span><span style="color: var(--shiki-color-text)">) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) data: any' >data</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='any' >dividend</data-lsp> </span><span style="color: var(--shiki-token-keyword)">/</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) data: any' >data</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='any' >divisor</data-lsp>;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> }</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-function)"><data-lsp lsp='function calculate<"add">(operation: "add", data: { addend_1: number; addend_2: number; }): number | undefined' >calculate</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'add'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) addend_1: number' >addend_1</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) addend_2: number' >addend_2</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-color-text)"> });</span></div><div class='line'><span style="color: var(--shiki-token-function)"><data-lsp lsp='function calculate<"divide">(operation: "divide", data: { dividend: number; divisor: number; }): number | undefined' >calculate</data-lsp></span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'divide'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) dividend: number' >dividend</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">42</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) divisor: number' >divisor</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">7</span><span style="color: var(--shiki-color-text)"> });</span></div></code></div></pre>`),a(u);var P=t(u,6),Ms=s(P);o(Ms,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement(arr: string[] | number[]): string | number' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) arr: string[] | number[]' >arr</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">[])</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) arr: string[] | number[]' >arr</data-lsp>[</span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">];
15</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div></code></div></pre>`),a(P);var f=t(P,6),zs=s(f);o(zs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-comment)">// return string when passed string[]</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement(arr: string[]): string (+1 overload)' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) arr: string[]' >arr</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[])</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// return number when passed number[]</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement(arr: number[]): number (+1 overload)' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) arr: number[]' >arr</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">[])</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// then the actual implementation</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement(arr: string[]): string (+1 overload)' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">(<data-lsp lsp='(parameter) arr: any' >arr</data-lsp>) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) arr: any' >arr</data-lsp>[</span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">];</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const string: string' style='border-bottom: solid 2px lightgrey;'>string</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement(arr: string[]): string (+1 overload)' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([</span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'c'</span><span style="color: var(--shiki-color-text)">]);
15</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const string: string</span></div></code></div></pre>`),a(f);var w=t(f,4),Xs=s(w);o(Xs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-comment)">// Define type parameter `Item` and describe argument and return type in terms of `Item`</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<Item>(arr: Item[]): Item | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)">>(<data-lsp lsp='(parameter) arr: Item[]' >arr</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)">[])</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">undefined</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) arr: Item[]' >arr</data-lsp>[</span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">];</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div></code></div></pre>`),a(w);var b=t(w,4),qs=s(b);o(qs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="4"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const obj: { a: number; } | undefined' style='border-bottom: solid 2px lightgrey;'>obj</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<{ a: number; }>(arr: { a: number; }[]): { a: number; } | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([{ <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-color-text)"> }</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-color-text)"> }</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">5</span><span style="color: var(--shiki-color-text)"> }]);</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>const obj: { 16 a: number; 17} | undefined</span></div></code></div></pre>`),a(b);var ks=t(b,8),Gs=s(ks);o(Gs,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-comment)">// `Item` can only be of `string` or `number`</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<Item extends string | number>(arr: Item[]): Item | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item extends string | number>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">>(<data-lsp lsp='(parameter) arr: Item[]' >arr</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item extends string | number>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)">[])</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Item in firstElement<Item extends string | number>(arr: Item[]): Item | undefined' >Item</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">undefined</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) arr: Item[]' >arr</data-lsp>[</span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">];
17</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const number: 1 | 3 | 5 | undefined' >number</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<1 | 3 | 5>(arr: (1 | 3 | 5)[]): 1 | 3 | 5 | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([</span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">5</span><span style="color: var(--shiki-color-text)">]);</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const obj: string | number | undefined' >obj</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function firstElement<string | number>(arr: (string | number)[]): string | number | undefined' >firstElement</data-lsp></span><span style="color: var(--shiki-color-text)">([{ <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)"><data-err>:</data-err></span><span style="color: var(--shiki-color-text)"><data-err> </data-err></span><span style="color: var(--shiki-token-constant)"><data-err>1</data-err></span><span style="color: var(--shiki-color-text)"><data-err> }</data-err></span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)"><data-err>:</data-err></span><span style="color: var(--shiki-color-text)"><data-err> </data-err></span><span style="color: var(--shiki-token-constant)"><data-err>3</data-err></span><span style="color: var(--shiki-color-text)"><data-err> }</data-err></span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)"><data-err>:</data-err></span><span style="color: var(--shiki-color-text)"><data-err> </data-err></span><span style="color: var(--shiki-token-constant)"><data-err>5</data-err></span><span style="color: var(--shiki-color-text)"> }]);</span></div><span class="error"><span>Type '{ a: number; }' is not assignable to type 'string | number'.</br>Type '{ a: number; }' is not assignable to type 'string | number'.</br>Type '{ a: number; }' is not assignable to type 'string | number'.</span><span class="code">2322<br/>2322<br/>2322</span></span><span class="error-behind">Type '{ a: number; }' is not assignable to type 'string | number'.</br>Type '{ a: number; }' is not assignable to type 'string | number'.</br>Type '{ a: number; }' is not assignable to type 'string | number'.</span></code></div></pre>`),a(ks),a(m);var A=t(m,2),ys=t(s(A),4),Ls=s(ys);o(Ls,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">
17get</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">>(path</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> callback</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">CallbackFn</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">>)</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)"> {</span></span> 18<span class="line"><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-comment)">// impplementation</span></span> 19<span class="line"><span style="color: var(--shiki-color-text)">}</span></span> 20<span class="line"></span> 21<span class="line"><span style="color: var(--shiki-token-function)">get</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">'/docs/[chapter]/[section]/args/[...args]'</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> (req) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></span> 22<span class="line"><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)">params</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> req;</span></span> 23<span class="line"><span style="color: var(--shiki-color-text)">});</span></span></code></pre>`),a(ys),e(2),a(A);var I=t(A,2),K=t(s(I),6),Ws=s(K);o(Ws,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>'),a(K);var B=t(K,4),Js=s(B);o(Js,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'purchase'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'args'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>'),a(B);var S=t(B,4),Qs=s(S);o(Qs,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">FilteredParts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>'),a(S);var $=t(S,4),Us=s($);o(Us,()=>
23'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">FilteredParts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>'),a($);var F=t($,4),Ys=s(F);o(Ys,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Params</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span> 24<span class="line"><span style="color: var(--shiki-color-text)"> shopid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></span> 25<span class="line"><span style="color: var(--shiki-color-text)"> itemid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></span> 26<span class="line"><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></span> 27<span class="line"><span style="color: var(--shiki-color-text)">};</span></span></code></pre>`),a(F);var _=t(F,4),Zs=s(_);o(Zs,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Params</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span> 28<span class="line"><span style="color: var(--shiki-color-text)"> shopid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span> 29<span class="line"><span style="color: var(--shiki-color-text)"> itemid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span> 30<span class="line"><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[];</span></span> 31<span class="line"><span style="color: var(--shiki-color-text)">};</span></span></code></pre>`),a(_);var V=t(_,4),sa=s(V);o(sa,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Params</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span> 32<span class="line"><span style="color: var(--shiki-color-text)"> shopid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span> 33<span class="line"><span style="color: var(--shiki-color-text)"> itemid</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span> 34<span class="line"><span style="color: var(--shiki-color-text)"> args</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[];</span></span> 35<span class="line"><span style="color: var(--shiki-color-text)">};</span></span></code></pre>`),a(V);var ds=t(V,4),aa=s(ds);o(aa,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">CallbackFn</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> (req</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { params</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Params</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)">Path</span><span style="color: var(--shiki-color-text)">> }) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>'),a(ds),a(I);var R=t(I,2),T=t(s(R),4),ta=s(T);o(ta,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends "a/b" ? "a" | "b" : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`a/b`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type AB = "a" | "b"' style='border-bottom: solid 2px lightgrey;'>AB</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends "a/b" ? "a" | "b" : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type AB = "a" | "b"</span></div></code></div></pre>`),a(T);var N=t(T,4),oa=s(N);o(oa,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">CD</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'c/d'</span><span style="color: var(--shiki-color-text)">>;</span></span> 36<span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">EF</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'e/f'</span><span style="color: var(--shiki-color-text)">>;</span></span></code></pre>`),a(N);
36var C=t(N,4),ea=s(C);o(ea,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type AB = "a" | "b"' style='border-bottom: solid 2px lightgrey;'>AB</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type AB = "a" | "b"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type CD = "c" | "d"' style='border-bottom: solid 2px lightgrey;'>CD</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'c/d'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type CD = "c" | "d"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type EFGH = "ef" | "gh"' style='border-bottom: solid 2px lightgrey;'>EFGH</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : never' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'ef/gh'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type EFGH = "ef" | "gh"</span></div></code></div></pre>`),a(C);var H=t(C,4),ra=s(H);o(ra,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = "a"' style='border-bottom: solid 2px lightgrey;'>A</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type A = "a"</span></div></code></div></pre>`),a(H);var D=t(H,4),na=s(D);o(na,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="2"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ABCD = "a" | "b/c/d"' style='border-bottom: solid 2px lightgrey;'>ABCD</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | PartB : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ABCD = "a" | "b/c/d"</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// type PartA = 'a';</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// type PartB = 'b/c/d';</span></div></code></div></pre>`),a(D);var j=t(D,4),la=s(j);o(la,()=>`<div class="filename">Step 1: Parts<Path></div><div class="copy" data-copy="type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` 37 ? PartA | Parts<PartB> 38 : Path; 39 40type ABCD = Parts<'a/b/c/d'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 1: Parts<Path>" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | Parts<PartB> : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | Parts<PartB> : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Parts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ABCD = "a" | "b" | "c" | "d"' style='border-bottom: solid 2px lightgrey;'>ABCD</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><s
40pan style="color: var(--shiki-token-function)"><data-lsp lsp='type Parts<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA | Parts<PartB> : Path' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ABCD = "a" | "b" | "c" | "d"</span></div></code></div></pre>`),a(j);var vs=t(j,4),ia=s(vs);o(ia,()=>`<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'b/c/d'</span><span style="color: var(--shiki-color-text)">>;</span></span> 41<span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'c/d'</span><span style="color: var(--shiki-color-text)">>;</span></span> 42<span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'c'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'d'</span><span style="color: var(--shiki-color-text)">>;</span></span> 43<span class="line"><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Parts</span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'a/b/c/d'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'b'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'c'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'d'</span><span style="color: var(--shiki-color-text)">;</span></span></code></pre>`),a(vs),a(R);var E=t(R,2),O=t(s(E),4),pa=s(O);o(pa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type A = "a"' style='border-bottom: solid 2px lightgrey;'>A</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'a'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type A = "a"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Obj = { a: 1; }' style='border-bottom: solid 2px lightgrey;'>Obj</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: 1' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Obj = { 44 a: 1; 45}</span></div></code></div></pre>`),a(O);var M=t(O,4),ca=s(M);o(ca,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-string-expression)">'purchase'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'args'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span></span></code></pre>'),a(M);var z=t(M,4),ka=s(z);o(ka,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-color-text)">never </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> never </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span></span></code></pre>'),a(z);var X=t(z,4),ya=s(X);o(ya,()=>'<pre class="shiki" style="background-color: var(--shiki-color-background)"><code><span class="line"><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span></span></code></pre>'),a(X);var q=t(X,6),da=s(q);o(da,()=>`<div class="filename">IsParameter<Part></div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never; 46type Purchase = IsParameter<'purchase'>; 47type ShopId = IsParameter<'[shopid]'>; 48type ItemId = IsParameter<'[itemid]'>; 49type Args = IsParameter<'args'>; 50type Args2 = IsParameter<'[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" copy="true" filename="IsParameter<Part>"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >
50Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Purchase = never' style='border-bottom: solid 2px lightgrey;'>Purchase</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'purchase'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Purchase = never</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ShopId = "[shopid]"' style='border-bottom: solid 2px lightgrey;'>ShopId</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'[shopid]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ShopId = "[shopid]"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ItemId = "[itemid]"' style='border-bottom: solid 2px lightgrey;'>ItemId</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'[itemid]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ItemId = "[itemid]"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Args = never' style='border-bottom: solid 2px lightgrey;'>Args</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'args'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Args = never</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Args2 = "[...args]"' style='border-bottom: solid 2px lightgrey;'>Args2</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Args2 = "[...args]"</span></div></code></div></pre>`),a(q);var hs=t(q,6),va=s(hs);o(va,()=>`<div class="filename">Step 2: FilteredParts<Path></div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never; 51type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 52 ? IsParameter<PartA> | FilteredParts<PartB> 53 : IsParameter<Path>; 54 55type Params = FilteredParts<'/purchase/[shopid]/[itemid]/args/[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 2: FilteredParts<Path>" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line highlight'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >
55Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer Anything}]` ? Part : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params = "[shopid]" | "[itemid]" | "[...args]"' style='border-bottom: solid 2px lightgrey;'>Params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Params = "[shopid]" | "[itemid]" | "[...args]"</span></div></code></div></pre>`),a(hs),a(E);var G=t(E,2),xs=t(s(G),8),ha=s(xs);
55o(ha,()=>`<div class="filename">Step 3: ParamsWithoutBracket</div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; 56type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 57 ? IsParameter<PartA> | FilteredParts<PartB> 58 : IsParameter<Path>; 59 60type ParamsWithoutBracket = FilteredParts<'/purchase/[shopid]/[itemid]/args/[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 3: ParamsWithoutBracket" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line highlight'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamsWithoutBracket = "shopid" | "itemid" | "...args"' >ParamsWithoutBracket</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div></code></div></pre>`),a(xs),a(G);var L=t(G,2),W=t(s(L),6),xa=s(W);o(xa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params = { shopid: any; itemid: any; '...args': any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) shopid: any' >shopid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) itemid: any' >itemid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div></code></div></pre>`),a(W);var J=t(W,4),ma=s(J);o(ma,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params = { [key: string]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> [<data-lsp lsp='(parameter) key: string' >key</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const params: Params' >params</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params = { [key: string]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) a: number' >a</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) b: number' >b</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) shopid: number' >shopid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-color-text)"> };</span></div></code></div></pre>`),a(J);var Q=t(J,4),ga=s(Q);o(ga,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Keys extends string> = { [Key in Keys]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Keys in type Params<Keys extends string>' >Keys</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Keys in type Params<Keys extends string>' >Keys</data-lsp></span><span style="color: var(--shiki-color-text)">]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const params: Params<"shopid" | "itemid" | "...args">' >params</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Keys extends string> = { [Key in Keys]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'
60</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) shopid: any' >shopid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) itemid: any' >itemid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">4</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='const incorrect_keys: Params<"shopid" | "itemid" | "...args">' >incorrect_keys</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Keys extends string> = { [Key in Keys]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-err><data-lsp lsp='(property) a: number' >a</data-lsp></data-err></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1</span><span style="color: var(--shiki-token-punctuation)">,</span></div><span class="error"><span>Object literal may only specify known properties, and 'a' does not exist in type 'Params<"shopid" | "itemid" | "...args">'.</span><span class="code">2353</span></span><span class="error-behind">Object literal may only specify known properties, and 'a' does not exist in type 'Params<"shopid" | "itemid" | "...args">'.</span><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) b: number' >b</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) shopid: any' >shopid</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-token-punctuation)">,</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div></code></div></pre>`),a(Q);var ms=t(Q,4),ua=s(ms);o(ua,()=>`<div class="filename">Step 4: Params<Path></div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; 61type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 62 ? IsParameter<PartA> | FilteredParts<PartB> 63 : IsParameter<Path>; 64type Params<Path> = { 65 [Key in FilteredParts<Path>]: any; 66}; 67 68type ParamObject = Params<'/purchase/[shopid]/[itemid]/args/[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 4: Params<Path>" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line highlight'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path>]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)">};</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamObject = { shopid: any; itemid: any; "...args": any; }' style='border-bottom: solid 2px lightgrey;'>ParamObject</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path>]: any; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ParamObject = { 69 shopid: any; 70 itemid: any; 71 "...args": any; 72}</span></div></code></div></pre>`),a(ms),a(L);var U=t(L,2),Y=t(s(U),10),Pa=s(Y);o(Pa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`
72...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ShopIdValue = number' style='border-bottom: solid 2px lightgrey;'>ShopIdValue</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ShopIdValue = number</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ArgValue = string[]' style='border-bottom: solid 2px lightgrey;'>ArgValue</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ArgValue = string[]</span></div></code></div></pre>`),a(Y);var Z=t(Y,8),fa=s(Z);o(fa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="2"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Parts extends string> = { [Key in Parts]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Parts in type Params<Parts extends string>' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Parts in type Params<Parts extends string>' >Parts</data-lsp></span><span style="color: var(--shiki-color-text)">]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamObject = { shopid: number; itemid: number; "...args": string[]; }' >ParamObject</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Parts extends string> = { [Key in Parts]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">>;</span></div></code></div></pre>`),a(Z);var ss=t(Z,4),wa=s(ss);o(wa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="2"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params = { shopid: ParamValue<"shopid">; itemid: ParamValue<"itemid">; '...args': ParamValue<"...args">; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'itemid'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div></code></div></pre>`),a(ss);var gs=t(ss,4),ba=s(gs);o(ba,()=>`<div class="filename">Step 5: Params<Path></div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; 73type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 74 ? IsParameter<PartA> | FilteredParts<PartB> 75 : IsParameter<Path>; 76type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number; 77type Params<Path> = { 78 [Key in FilteredParts<Path>]: ParamValue<Key>; 79}; 80 81type ParamObject = Params<'/purchase/[shopid]/[itemid]/args/[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 5: Params<Path>" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="co
81lor: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line highlight'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'><span style="color: var(--shiki-color-text)">};</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamObject = { shopid: number; itemid: number; "...args": string[]; }' style='border-bottom: solid 2px lightgrey;'>ParamObject</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ParamObject = { 82 shopid: number; 83 itemid: number; 84 "...args": string[]; 85}</span></div></code></div></pre>`),a(gs),a(U);var as=t(U,2),ts=t(s(as),4),Aa=s(ts);o(Aa,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`
85...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Args = "args"' style='border-bottom: solid 2px lightgrey;'>Args</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'...args'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type Args = "args"</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ShopId = "shopid"' style='border-bottom: solid 2px lightgrey;'>ShopId</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'shopid'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ShopId = "shopid"</span></div></code></div></pre>`),a(ts);var us=t(ts,4),Ia=s(us);o(Ia,()=>`<div class="filename">Step 7: Params<Path></div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; 86type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 87 ? IsParameter<PartA> | FilteredParts<PartB> 88 : IsParameter<Path>; 89type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number; 90type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key; 91type Params<Path> = { 92 [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; 93}; 94 95type ParamObject = Params<'/purchase/[shopid]/[itemid]/args/[...args]'>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Step 7: Params<Path>" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`
95...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'><span style="color: var(--shiki-color-text)">};</span></div><div class='line dim'> </div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamObject = { shopid: number; itemid: number; args: string[]; }' style='border-bottom: solid 2px lightgrey;'>ParamObject</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'/purchase/[shopid]/[itemid]/args/[...args]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type ParamObject = { 96 shopid: number; 97 itemid: number; 98 args: string[]; 99}</span></div></code></div></pre>`),a(us),e(2),a(as);var os=t(as,2),Ps=t(s(os),4),Ka=s(Ps);o(Ka,()=>`<div class="filename">Solution</div><div class="copy" data-copy="type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; 100type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` 101 ? IsParameter<PartA> | FilteredParts<PartB> 102 : IsParameter<Path>; 103type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number; 104type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key; 105type Params<Path> = { 106 [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; 107}; 108type CallbackFn<Path> = (req: { params: Params<Path> }
108) => void; 109 110function get<Path extends string>(path: Path, callback: CallbackFn<Path>) { 111 // TODO: implement 112}"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" filename="Solution" copy="true"><div class="language-id">ts</div><div class='code-container'><code><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Part in type IsParameter<Part>' >Part</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`[</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">]`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) ParamName' >ParamName</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartA' >PartA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) PartB' >PartB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never' >IsParameter</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type FilteredParts<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type ParamValue<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`
112...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Anything' >Anything</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">[] </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`...</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Name' >Name</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key in type RemovePrefixDots<Key>' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line dim'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | FilteredParts<PartB> : IsParameter<Path>' >FilteredParts</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type Params<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key' >RemovePrefixDots</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number' >ParamValue</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line dim'><span style="color: var(--shiki-color-text)">};</span></div><div class='line dim'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type CallbackFn<Path> = (req: { params: Params<Path>; }
112) => void' >CallbackFn</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type CallbackFn<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) req: { params: Params<Path>; }' >req</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) params: Params<Path>' >params</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Params<Path> = { [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; }' >Params</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type CallbackFn<Path>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> }) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line dim'> </div><div class='line highlight'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function get<Path extends string>(path: Path, callback: CallbackFn<Path>): void' >get</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in get<Path extends string>(path: Path, callback: CallbackFn<Path>): void' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">>(<data-lsp lsp='(parameter) path: Path extends string' >path</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in get<Path extends string>(path: Path, callback: CallbackFn<Path>): void' >Path</data-lsp></span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(parameter) callback: CallbackFn<Path>' >callback</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type CallbackFn<Path> = (req: { params: Params<Path>; }) => void' >CallbackFn</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in get<Path extends string>(path: Path, callback: CallbackFn<Path>): void' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>) {</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-comment)">// TODO: implement</span></div><div class='line highlight'><span style="color: var(--shiki-color-text)">}</span></div></code></div></pre>`),a(Ps),a(os);var es=t(os,2),fs=t(s(es),8),Ba=s(fs);o(Ba,()=>`<pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="ts" cutLines="38"><div class="language-id">ts</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-comment)">// `Parse`
112 parses string into a nested string array of infinite level deep</span></div><div class='line'><span style="color: var(--shiki-token-comment)">// type Parse<Str extends string> = ?;</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type EmptyArray = []' style='border-bottom: solid 2px lightgrey;'>EmptyArray</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parse<Str extends string> = ParseStringArray<Str, []> extends [infer Remaining, infer Result] ? Remaining extends "" ? Result : never : never' >Parse</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'[]'</span><span style="color: var(--shiki-color-text)">>;</span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type EmptyArray = []</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type StringArray = ["hello", "world"]' style='border-bottom: solid 2px lightgrey;'>StringArray</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parse<Str extends string> = ParseStringArray<Str, []> extends [infer Remaining, infer Result] ? Remaining extends "" ? Result : never : never' >Parse</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'["hello", "world"]'</span><span style="color: var(--shiki-color-text)">></span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type StringArray = ["hello", "world"]</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type NestedArray = ["hello", ["world", "ts", ["!"]], ["try this"]]' style='border-bottom: solid 2px lightgrey;'>NestedArray</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type Parse<Str extends string> = ParseStringArray<Str, []> extends [infer Remaining, infer Result] ? Remaining extends "" ? Result : never : never' >Parse</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-string-expression)">'["hello", ["world", "ts", ["!"]], ["try this"]]'</span><span style="color: var(--shiki-color-text)">></span></div><div class='meta-line'><span class='popover-prefix'> </span><span class='popover'><div class='arrow'></div>type NestedArray = ["hello", ["world", "ts", ["!"]], ["try this"]]</span></div></code></div></pre>`),a(fs),e(2),a(es);var ws=t(es,2),bs=t(s(ws),4),Sa=s(bs);o(Sa,()=>`<div class="filename">Route component</div><div class="copy" data-copy="import React from 'react'; 113 114type PathSegments<Path extends string> = Path extends `${infer SegmentA}/${infer SegmentB}` 115 ? ParamOnly<SegmentA> | PathSegments<SegmentB> 116 : ParamOnly<Path>; 117type ParamOnly<Segment extends string> = Segment extends `:${infer Param}` 118 ? Param 119 : never; 120type RouteParams<Path extends string> = { 121 [Key in PathSegments<Path>]: string; 122}; 123 124function Route<Path extends string>({}: { 125 path: Path; 126 render: (routeProps: { 127 match: {
127 params: RouteParams<Path> }; 128 }) => void; 129}) { 130 return <div />; 131} 132 133<Route 134 path="/user/:username" 135 render={(routeProps) => { 136 const params = routeProps.match.params; 137 }} 138/>;"><svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg></div><pre class="shiki twoslash lsp" style="background-color: var(--shiki-color-background); color: var(--shiki-color-text)" lang="tsx" filename="Route component" copy="true"><div class="language-id">tsx</div><div class='code-container'><code><div class='line'><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(alias) namespace React import React' >React</data-lsp> </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">'react'</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type PathSegments<Path extends string> = Path extends `${infer SegmentA}/${infer SegmentB}` ? ParamOnly<SegmentA> | PathSegments<SegmentB> : ParamOnly<Path>' >PathSegments</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type PathSegments<Path extends string>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type PathSegments<Path extends string>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) SegmentA' >SegmentA</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) SegmentB' >SegmentB</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamOnly<Segment extends string> = Segment extends `:${infer Param}` ? Param : never' >ParamOnly</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) SegmentA' >SegmentA</data-lsp></span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type PathSegments<Path extends string> = Path extends `${infer SegmentA}/${infer SegmentB}` ? ParamOnly<SegmentA> | PathSegments<SegmentB> : ParamOnly<Path>' >PathSegments</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) SegmentB' >SegmentB</data-lsp></span><span style="color: var(--shiki-color-text)">></span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamOnly<Segment extends string> = Segment extends `:${infer Param}` ? Param : never' >ParamOnly</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type PathSegments<Path extends string>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type ParamOnly<Segment extends string> = Segment extends `:${infer Param}` ? Param : never' >ParamOnly</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Segment in type ParamOnly<Segment extends string>' >Segment</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Segment in type ParamOnly<Segment extends string>' >Segment</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`:</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-keyword)">infer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Param' >Param</data-lsp></span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Param' >Param</data-lsp></span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">never</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">
138<data-lsp lsp='type RouteParams<Path extends string> = { [Key in PathSegments<Path>]: string; }' >RouteParams</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type RouteParams<Path extends string>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Key' >Key</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">in</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type PathSegments<Path extends string> = Path extends `${infer SegmentA}/${infer SegmentB}` ? ParamOnly<SegmentA> | PathSegments<SegmentB> : ParamOnly<Path>' >PathSegments</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in type RouteParams<Path extends string>' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">>]</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)">};</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='function Route<Path extends string>({}: { path: Path; render: (routeProps: { match: { params: RouteParams<Path>; }; }) => void; }): React.JSX.Element' >Route</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in Route<Path extends string>({}: { path: Path; render: (routeProps: { match: { params: RouteParams<Path>; }; }) => void; }): React.JSX.Element' >Path</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">>({}</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) path: Path extends string' >path</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in Route<Path extends string>({}: { path: Path; render: (routeProps: { match: { params: RouteParams<Path>; }; }) => void; }): React.JSX.Element' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(property) render: (routeProps: { match: {
138 params: RouteParams<Path>; }; }) => void' >render</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> (<data-lsp lsp='(parameter) routeProps: { match: { params: RouteParams<Path>; }; }' >routeProps</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> <data-lsp lsp='(property) match: { params: RouteParams<Path>; }' >match</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { <data-lsp lsp='(property) params: RouteParams<Path>' >params</data-lsp></span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='type RouteParams<Path extends string> = { [Key in PathSegments<Path>]: string; }' >RouteParams</data-lsp></span><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(type parameter) Path in Route<Path extends string>({}: { path: Path; render: (routeProps: { match: { params: RouteParams<Path>; }; }) => void; }): React.JSX.Element' >Path</data-lsp></span><span style="color: var(--shiki-color-text)">> };</span></div><div class='line'><span style="color: var(--shiki-color-text)"> }) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">;</span></div><div class='line'><span style="color: var(--shiki-color-text)">}) {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> <</span><span style="color: var(--shiki-token-string-expression)"><data-lsp lsp='(property) JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>' >div</data-lsp></span><span style="color: var(--shiki-color-text)"> />;</span></div><div class='line'><span style="color: var(--shiki-color-text)">}</span></div><div class='line'> </div><div class='line'><span style="color: var(--shiki-color-text)"><</span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='function Route<"/user/:username">({}: { path: "/user/:username"; render: (routeProps: { match: { params: RouteParams<"/user/:username">; }; }) => void; }): React.JSX.Element' >Route</data-lsp></span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(property) path: "/user/:username"' >path</data-lsp></span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"/user/:username"</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)"><data-lsp lsp='(property) render: (routeProps: { match: { params: RouteParams<"/user/:username">; }; }) => void' >render</data-lsp></span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)">{(<data-lsp lsp='(parameter) routeProps: { match: { params: RouteParams<"/user/:username">; }; }' >routeProps</data-lsp>) </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></div><div class='line'><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">
138<data-lsp lsp='const params: RouteParams<"/user/:username">' >params</data-lsp></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(parameter) routeProps: { match: { params: RouteParams<"/user/:username">; }; }' >routeProps</data-lsp></span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)"><data-lsp lsp='(property) match: { params: RouteParams<"/user/:username">; }' >match</data-lsp></span><span style="color: var(--shiki-color-text)">.<data-lsp lsp='(property) params: RouteParams<"/user/:username">' >params</data-lsp>;</span></div><div class='line'><span style="color: var(--shiki-color-text)"> }}</span></div><div class='line'><span style="color: var(--shiki-color-text)">/>;</span></div></code></div></pre>`),a(bs),a(ws),e(2),Ta(Bs,ns)},$$slots:{default:!0}})),_a()}export{tt as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.