@TypedParam
export function TypedParam(name: string): ParameterDecorator;Drop-in replacement for @Param("name") from @nestjs/common. Identical behavior plus:
- The path parameter is coerced to the TypeScript type (
"42"→42,"true"→true,"null"→null). - The coerced value is validated — invalid
uuid, out-of-rangenumber, malformeddate, etc. become a400 Bad Request. - The parameter is visible to
@nestia/sdk— appears in the generated SDK with the same type your handler sees.
Vanilla @Param("id") always gives you a string. @TypedParam("id") gives you exactly the type you declared.
Basic usage
import { TypedParam, TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";
import { tags } from "typia";
@Controller("articles")
export class ArticlesController {
// Path: GET /articles/2b5e21d8-0e44-4482-bd3e-4540dee7f3d6
// `id` is typed as `string & tags.Format<"uuid">`
@TypedRoute.Get(":id")
public async at(
@TypedParam("id") id: string & tags.Format<"uuid">,
): Promise<IArticle> { ... }
// Path: GET /articles/section/general/page/42
// `section` is `string`, `page` is `number & tags.Type<"uint32">`
@TypedRoute.Get("section/:section/page/:page")
public async list(
@TypedParam("section") section: string,
@TypedParam("page") page: number & tags.Type<"uint32">,
): Promise<IPage<IArticle>> { ... }
}The string "42" arrives at the wire, but page in your handler is already a number. A request to /articles/section/general/page/abc returns 400 before your handler is called.
Supported parameter types
| Type | Wire example | Coerces to |
|---|---|---|
string | "hello" | "hello" |
string & tags.Format<"uuid"> | "2b5e2…" | "2b5e2…" (validated) |
string & tags.Format<"date"> | "2024-04-01" | "2024-04-01" (validated) |
number | "42" | 42 |
number & tags.Type<"uint32"> | "42" | 42 (validated) |
boolean | "true" / "false" | true / false |
null | "null" | null |
"a" | "b" | "c" | "a" | "a" (validated) |
Nullable: T | null | as above | T or null |
Tags layered on top (MinLength, Maximum, Pattern, etc.) work the same as on body / query types.
Path parameters are flat by definition — you cannot decode a nested object out of a single segment. If you need an object, use @TypedQuery or @TypedBody.
When to use plain @Param instead
Reach for the vanilla decorator when:
- The param is consumed by NestJS-only middleware that expects raw strings.
- You’re migrating a route piecewise and don’t want to add the dependency yet.
Vanilla params are invisible to @nestia/sdk’s generators.
Common pitfalls
Validation is on the coerced value, not the raw string. A path of /articles/abc against @TypedParam("id") id: number fails because "abc" cannot become a number — the error is coercion, not a Minimum<…> violation. The 400 response distinguishes between them.
Path-only. @TypedParam reads from path parameters (:name in the route). For querystring values use @TypedQuery; for headers, @TypedHeaders.
See also
- TypedQuery — query-string parameters, including nested DTOs.
- TypedBody — JSON request bodies.
- TypedRoute — the route decorators these parameters live on.