End-to-End Types
Notation's type system spans infrastructure definitions and runtime handlers, catching mismatches before deployment.
Type-safe handlers
When you wire a handler to an API Gateway route, TypeScript ensures the handler's signature matches the expected event shape:
import { api, router } from "@notation/aws/api-gateway";
import { getUser } from "runtime/user.fn";
const myApi = api({ name: "user-api" });
const myRouter = router(myApi);
myRouter.get("/user", getUser);import { handle, json } from "@notation/aws/lambda.fn";
export const getUser = handle.apiRequest((event) => {
return json({ id: 1, name: "Alice" });
});The handle.apiRequest wrapper types event as an API Gateway v2 HTTP event. If you pass a handler with the wrong event type to the router, TypeScript catches it at compile time.
JWT authorizer types
When using a JWT authorizer, claims types flow from infrastructure to handler:
import { api, router } from "@notation/aws/api-gateway";
import { getUser } from "runtime/user.fn";
type JWTClaims = { sub: string; email: string };
const myApi = api({ name: "user-api" });
const authedRouter = router(myApi).withJWTAuthorizer<JWTClaims>({
type: "jwt",
issuer: "https://auth.example.com/",
audience: ["https://api.example.com"],
scopes: [],
});
authedRouter.get("/user", getUser);import { handle, json } from "@notation/aws/lambda.fn";
export const getUser = handle.jwtAuthorizedApiRequest<JWTClaims>((event) => {
// event.requestContext.authorizer.jwt.claims is typed as JWTClaims
const { sub, email } = event.requestContext.authorizer.jwt.claims;
return json({ sub, email });
});The same pattern applies to other event sources (EventBridge, DynamoDB streams, SQS). Each handle.* wrapper types the event to match its source.