Inspired by https://twitter.com/TkDodo/status/1734255363266843017?t=dOhCHPJJMd2bq2A8VK8R-A&s=19
Last active
December 11, 2023 19:30
-
-
Save mykeels/587e7933753e053cec5cbb783a8491e2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Path matching | |
------- | |
by Mykeels (@mykeels) #urls | |
See tests below | |
*/ | |
/* _____________ Your Code Here _____________ */ | |
type Paths = '/abc' | '/foo/:id' | '/bar' | (string & {}); | |
declare function FooComponent<TPath extends Paths, TPathTemplate extends Paths.TemplateOf<TPath>>( | |
props: { | |
href: TPathTemplate extends Paths.Templates ? TPath : never | |
} | |
): any; | |
declare namespace Paths { | |
type Templates = Template<Paths>; | |
type Template<T extends string> = | |
T extends `${infer Prefix}:${infer Param}/${infer Rest}` | |
? `${Prefix}${string}/${Template<Rest>}` | |
: T extends `${infer Prefix}:${infer Rest}` | |
? `${Prefix}${string}` | |
: T; | |
type TemplateOf< | |
TPath extends string, | |
TPathTemplate extends Templates = Templates | |
> = TPathTemplate extends infer T extends string | |
? TPath extends T | |
? TPath extends `${T}/${string}` | |
? never | |
: T | |
: never | |
: never; | |
} | |
/* _____________ Test Cases _____________ */ | |
import type { Equal, Expect } from '@type-challenges/utils' | |
type testCases = [ | |
Expect< | |
Equal<Paths.TemplateOf<`/foo/hello`>, `/foo/${string}`> | |
>, | |
Expect< | |
Equal<Paths.TemplateOf<`/abc`>, `/abc`> | |
>, | |
Expect< | |
Equal< | |
Paths.TemplateOf<`/foo/abc/bar`>, | |
never | |
> | |
>, | |
]; | |
const urls = [ | |
FooComponent({ | |
href: '/bar' | |
}), | |
FooComponent({ | |
href: '/foo/hello' | |
}), | |
FooComponent({ | |
// @ts-expect-error | |
href: '/foo/hello/wrong-url' | |
}), | |
FooComponent({ | |
href: '/abc' | |
}), | |
FooComponent({ | |
// @ts-expect-error | |
href: '/wrong-url' | |
}), | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment