# Join

Infers the normalized path, intersected decoded parameters, and codec services of joined Routes.

## Signatures

```ts
export type Join<Routes extends ReadonlyArray<Route<any, any>>> = [
    Route<RouteJoinPath<Routes>, Schema.Codec<Simplify<UnionToIntersection<Routes[number]["paramsSchema"]["Type"]>>, Path.Params<RouteJoinPath<Routes>>, Routes[number]["paramsSchema"]["DecodingServices"], Routes[number]["paramsSchema"]["EncodingServices"]>>
] extends [
    Route<infer Path, infer Schema>
] ? Route<Path, Schema> : never;
```

```ts
export declare const Join: <const Routes extends AnyRoutes>(...routes: Routes) => Join<FlattenRoutes<Routes>>;
```

## Ownership and lifetime

TypeScript computes `Join` from its Route input; the alias is erased and owns no runtime value.

## Examples

```ts
import * as Router from "@typed/router"

const Workspace = Router.Join(Router.Parse("/workspaces"), Router.Param("workspaceId"))
const Issue = Router.Join(Workspace, Router.Parse("/issues"), Router.Int("issueId"))
type IssueInput = Router.Type<typeof Issue>
// { readonly workspaceId: string; readonly issueId: number }
```
