export interface SplitPattern { protocol: string | undefined hostname: string | undefined port: string | undefined pathname: string | undefined search: string | undefined } // prettier-ignore export type Split = _Split extends infer S extends Partial ? { protocol: S['protocol'] extends string ? S['protocol'] : undefined hostname: S['hostname'] extends string ? S['hostname'] : undefined port: S['port'] extends string ? S['port'] : undefined pathname: S['pathname'] extends string ? S['pathname'] : undefined search: S['search'] extends string ? S['search'] : undefined } : never // prettier-ignore type _Split = T extends '' ? {} : T extends `${infer L}?${infer R}` ? _Split & { search: R } : T extends `${infer Protocol}://${infer R}` ? Protocol extends '' ? ( R extends `${infer Host}/${infer Pathname}` ? SplitHost & { pathname: Pathname } : SplitHost ) : Protocol extends `${string}/${string}` ? { pathname: T } : R extends `${infer Host}/${infer Pathname}` ? SplitHost & { protocol: Protocol; pathname: Pathname } : SplitHost & { protocol: Protocol } : T extends `/${infer Pathname}` ? { pathname: Pathname } : { pathname: T } // prettier-ignore type SplitHost = T extends `${infer L}:${infer R}` ? IsDigits extends true ? { hostname: L; port: R} : SplitHost extends { hostname: infer H extends string; port: infer P extends string } ? { hostname: `${L}:${H}`; port: P } : { hostname: T } : { hostname: T } type _0_9 = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' // prettier-ignore type IsDigits = S extends `${_0_9}${infer T}` ? T extends '' ? true : IsDigits : false