import { IfNotUnion, IfNotString } from '../type' import warning from 'tiny-warning' export type Path = | string | string[] | RoutiderPath | RoutiderPaths /** * fake symbol for nominal typing */ declare const params: unique symbol /** * Type for valid path */ export type RoutiderPath = { readonly [params]: T } /** * Type for valid path and aliases */ export type RoutiderPaths< T extends string | undefined = string | undefined > = typeof params & RoutiderPath[] /** * Extracts params from RoutiderPath & RoutiderPaths */ export type ExtractParams = Exclude< T extends never ? never : T extends RoutiderPath ? P : T extends RoutiderPaths ? P : never, undefined > /** * Creates typed path. * * @example createPath`/items/${'id'}` */ export function createPath( literals: Readonly ): RoutiderPath export function createPath( literals: Readonly, ...placeholders: readonly T[] ): RoutiderPath> export function createPath( literals: Readonly, ...placeholders: readonly T[] ): RoutiderPath> { if (__DEV__) { const ps = new Set() for (const p of placeholders) { if (ps.has(p)) { console.warn( `vue-routider: duplicated param was passed to createPath. (${p})` ) } ps.add(p) } } let path = '' for (let i = 0; i < placeholders.length; i++) { const l = literals[i] const p = placeholders[i] path += `${l}:${p}` warning( !l.includes(':'), `vue-routider: \`:\` should not be included in createPath argument. (${l})` ) warning( !p.includes(':'), `vue-routider: \`:\` should not be included in createPath argument. (${p})` ) } const lastL = literals[literals.length - 1] path += lastL warning( !lastL.includes(':'), `vue-routider: \`:\` should not be included in createPath argument. (${lastL})` ) return (path as unknown) as RoutiderPath> } type PathArrayToPaths = T extends RoutiderPath ? RoutiderPaths : T[] export function createPaths< T extends readonly [RoutiderPath, RoutiderPath, ...RoutiderPath[]] >(...args: T): PathArrayToPaths> { return (args as unknown) as PathArrayToPaths> } export const pathToString = (path: RoutiderPath | string): string => path as string export const pathsToString = (paths: RoutiderPaths | string[]): string[] => paths as string[]