-
-
Notifications
You must be signed in to change notification settings - Fork 124
feat: add typescript types #197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,3 +3,4 @@ coverage/ | |
| node_modules/ | ||
| npm-debug.log | ||
| package-lock.json | ||
| *.lock | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import type { IncomingMessage, ServerResponse } from 'node:http' | ||
| import type { | ||
| Handler, | ||
| NextFunction, | ||
| RequestHandler, | ||
| Route as IRoute | ||
| } from './lib/route' | ||
| import Route = require('./lib/route') | ||
|
|
||
| export type RouterMethod<T> = <F extends Handler = RequestHandler>(path: Path, handler: F) => T | ||
|
|
||
| export type Path = string | RegExp | Array<string | RegExp> | ||
|
|
||
| interface RouterOptions { | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
| caseSensitive?: boolean | ||
| mergeParams?: boolean | ||
| strict?: boolean | ||
| } | ||
|
|
||
| interface Router extends RequestHandler { | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
| params: Record<string, any> | ||
| stack: any[] | ||
| caseSensitive: boolean | ||
| mergeParams: boolean | ||
| strict: boolean | ||
|
|
||
| handle(req: IncomingMessage, res: ServerResponse, callback: NextFunction): void | ||
| param(name: string, fn: (req: any, res: any, next: NextFunction, value: any, name: string) => void): this | ||
| route(path: Path): IRoute | ||
|
|
||
| use: { | ||
| <F extends Handler = RequestHandler>(path: Path, handler: F): Router | ||
| <F extends Handler = RequestHandler>(handler: F): Router | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| all: RouterMethod<this> | ||
| get: RouterMethod<this> | ||
| post: RouterMethod<this> | ||
| put: RouterMethod<this> | ||
| delete: RouterMethod<this> | ||
| patch: RouterMethod<this> | ||
| options: RouterMethod<this> | ||
| head: RouterMethod<this> | ||
| } | ||
|
|
||
| interface RouterConstructor { | ||
| (options?: RouterOptions): Router | ||
| new (options?: RouterOptions): Router | ||
| Route: typeof Route | ||
| } | ||
|
|
||
| declare const router: RouterConstructor | ||
| export = router | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're mixing this applies to both files. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import type { IncomingMessage, ServerResponse } from 'node:http' | ||
|
|
||
| export type NextFunction = (err?: any) => void | ||
|
|
||
| export type RequestHandler = (req: IncomingMessage, res: ServerResponse, next: NextFunction) => void | ||
| export type ErrorRequestHandler = (err: Error, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void | ||
|
|
||
| export type Handler = RequestHandler | ErrorRequestHandler | ||
|
|
||
| export type RouteMethod<T> = <F extends Handler = RequestHandler>(handler: F) => T | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
|
|
||
| export interface Route { | ||
| path: string | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like us to use the |
||
| stack: any[] | ||
| methods: Record<string, boolean> | ||
|
|
||
| _handlesMethod(method: string): boolean | ||
| _methods(): string[] | ||
| dispatch(req: IncomingMessage, res: ServerResponse, done: NextFunction): void | ||
|
|
||
| all: RouteMethod<this> | ||
| get: RouteMethod<this> | ||
| post: RouteMethod<this> | ||
| put: RouteMethod<this> | ||
| delete: RouteMethod<this> | ||
| patch: RouteMethod<this> | ||
| options: RouteMethod<this> | ||
| head: RouteMethod<this> | ||
| } | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
|
|
||
| interface RouteConstructor { | ||
| (path: string): Route | ||
| new (path: string): Route | ||
|
gameroman marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| declare const Route: RouteConstructor | ||
| export = Route | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { IncomingMessage, ServerResponse } from "node:http"; | ||
| import { expectTypeOf } from "expect-type"; | ||
| import Router from ".."; | ||
| import { ErrorRequestHandler } from "../lib/route"; | ||
|
|
||
| const router = Router(); | ||
|
|
||
| router.get("/", function (req, res) { | ||
| expectTypeOf(req).toEqualTypeOf<IncomingMessage>(); | ||
| expectTypeOf(res).toEqualTypeOf<ServerResponse>(); | ||
| }); | ||
|
|
||
| router.get("/", function (req, res, next) { | ||
| expectTypeOf(req).toEqualTypeOf<IncomingMessage>(); | ||
| expectTypeOf(res).toEqualTypeOf<ServerResponse>(); | ||
| expectTypeOf(next).toBeFunction(); | ||
| }); | ||
|
|
||
| // typescript has no way to infer the types automatically | ||
| router.get<ErrorRequestHandler>("/", function (err, req, res, next) { | ||
|
Comment on lines
+22
to
+23
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically, typescript can not automatically infer that the callback type is The only way to solve this is to change everything completely, changing callback's param to an object like This would obviously require a new major so I haven't touched anything there So just letting know that the current logic cannot be fully expressed in typescript without manually providing the type parameter on the user's side |
||
| expectTypeOf(err).toEqualTypeOf<Error>(); | ||
| expectTypeOf(req).toEqualTypeOf<IncomingMessage>(); | ||
| expectTypeOf(res).toEqualTypeOf<ServerResponse>(); | ||
| expectTypeOf(next).toBeFunction(); | ||
| }); | ||
|
gameroman marked this conversation as resolved.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "extends": "@tsconfig/node18/tsconfig.json", | ||
| "include": ["index.d.ts", "lib/route.d.ts", "test/types.ts"], | ||
| "compilerOptions": { | ||
| "types": ["node"] | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.