mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 10:56:53 +00:00
[express]: adding generics for query type (#43434)
* add-generics-to-query-type: adding generics for query type in express core * add-generics-to-query-type: fixing test case + lint * add-generics-to-query-type: updating the default query type for express * add-generics-to-query-type: fixing failed test cases * add-generics-to-query-type: fixing express-paginate-tests Co-authored-by: Puneet Arora <parora@atlassian.com>
This commit is contained in:
parent
df14f81746
commit
bb2673643a
@ -49,7 +49,7 @@ app.get('/hasrole', function (req, res, next) {
|
||||
});
|
||||
|
||||
app.post('/setrole', function (req, res, next) {
|
||||
req.session.setRole(req.query.role);
|
||||
req.session.setRole(req.query.role as string);
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
@ -59,4 +59,4 @@ app.get('/getrole', function (req, res, next) {
|
||||
|
||||
app.use(easySession.isLoggedIn());
|
||||
app.use(easySession.isFresh());
|
||||
app.use(easySession.checkRole('user'));
|
||||
app.use(easySession.checkRole('user'));
|
||||
|
||||
@ -12,7 +12,7 @@ app.get('/users', async (req, res, next) => {
|
||||
return findAndCountAll({limit: req.query.limit, offset: req.skip})
|
||||
.then(results => {
|
||||
const itemCount = results.count;
|
||||
const pageCount = Math.ceil(results.count / req.query.limit);
|
||||
const pageCount = Math.ceil(results.count / parseInt(req.query.limit as string, 10));
|
||||
res.render('users/all_users', {
|
||||
users: results.rows,
|
||||
pageCount,
|
||||
@ -20,7 +20,7 @@ app.get('/users', async (req, res, next) => {
|
||||
currentPageHref: paginate.href(req)(false, req.params),
|
||||
// Instead of exposing this to the html template, we'll test this here and pass a static number
|
||||
hasNextPages: paginate.hasNextPages(req)(pageCount),
|
||||
pages: paginate.getArrayPages(req)(3, pageCount, req.query.page)
|
||||
pages: paginate.getArrayPages(req)(3, pageCount, parseInt(req.query.page as string, 10))
|
||||
});
|
||||
}).catch(next);
|
||||
});
|
||||
|
||||
@ -32,6 +32,17 @@ app.get<{ foo: string }>('/:foo', req => {
|
||||
// Params cannot be a custom type that does not conform to constraint
|
||||
app.get<{ foo: number }>('/:foo', () => {}); // $ExpectError
|
||||
|
||||
// Query can be a custom type
|
||||
app.get<{}, any, any, {q: string}>('/:foo', req => {
|
||||
req.query.q; // $ExpectType string
|
||||
req.query.a; // $ExpectError
|
||||
});
|
||||
|
||||
// Query will be defaulted to Query type
|
||||
app.get('/:foo', req => {
|
||||
req.query; // $ExpectType Query
|
||||
});
|
||||
|
||||
// Default types
|
||||
app.post("/", (req, res) => {
|
||||
req.params[0]; // $ExpectType string
|
||||
|
||||
24
types/express-serve-static-core/index.d.ts
vendored
24
types/express-serve-static-core/index.d.ts
vendored
@ -40,26 +40,30 @@ export interface ParamsDictionary { [key: string]: string; }
|
||||
export type ParamsArray = string[];
|
||||
export type Params = ParamsDictionary | ParamsArray;
|
||||
|
||||
export interface RequestHandler<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any> {
|
||||
// Return type of qs.parse, the default query parser (https://expressjs.com/en/api.html#app-settings-property).
|
||||
export interface Query { [key: string]: string | string[] | Query | Query[]; }
|
||||
|
||||
export interface RequestHandler<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query> {
|
||||
// tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2
|
||||
(req: Request<P, ResBody, ReqBody>, res: Response<ResBody>, next: NextFunction): any;
|
||||
(req: Request<P, ResBody, ReqBody, ReqQuery>, res: Response<ResBody>, next: NextFunction): any;
|
||||
}
|
||||
|
||||
export type ErrorRequestHandler<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any> = (err: any, req: Request<P, ResBody, ReqBody>, res: Response<ResBody>, next: NextFunction) => any;
|
||||
export type ErrorRequestHandler<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query> =
|
||||
(err: any, req: Request<P, ResBody, ReqBody, ReqQuery>, res: Response<ResBody>, next: NextFunction) => any;
|
||||
|
||||
export type PathParams = string | RegExp | Array<string | RegExp>;
|
||||
|
||||
export type RequestHandlerParams<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any>
|
||||
= RequestHandler<P, ResBody, ReqBody>
|
||||
| ErrorRequestHandler<P, ResBody, ReqBody>
|
||||
export type RequestHandlerParams<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query>
|
||||
= RequestHandler<P, ResBody, ReqBody, ReqQuery>
|
||||
| ErrorRequestHandler<P, ResBody, ReqBody, ReqQuery>
|
||||
| Array<RequestHandler<P>
|
||||
| ErrorRequestHandler<P>>;
|
||||
|
||||
export interface IRouterMatcher<T, Method extends 'all' | 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head' = any> {
|
||||
// tslint:disable-next-line no-unnecessary-generics (This generic is meant to be passed explicitly.)
|
||||
<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any>(path: PathParams, ...handlers: Array<RequestHandler<P, ResBody, ReqBody>>): T;
|
||||
<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query>(path: PathParams, ...handlers: Array<RequestHandler<P, ResBody, ReqBody, ReqQuery>>): T;
|
||||
// tslint:disable-next-line no-unnecessary-generics (This generic is meant to be passed explicitly.)
|
||||
<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any>(path: PathParams, ...handlers: Array<RequestHandlerParams<P, ResBody, ReqBody>>): T;
|
||||
<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query>(path: PathParams, ...handlers: Array<RequestHandlerParams<P, ResBody, ReqBody, ReqQuery>>): T;
|
||||
(path: PathParams, subApplication: Application): T;
|
||||
}
|
||||
|
||||
@ -209,7 +213,7 @@ export type Errback = (err: Error) => void;
|
||||
* app.get<ParamsArray>(/user\/(.*)/, (req, res) => res.send(req.params[0]));
|
||||
* app.get<ParamsArray>('/user/*', (req, res) => res.send(req.params[0]));
|
||||
*/
|
||||
export interface Request<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any> extends http.IncomingMessage, Express.Request {
|
||||
export interface Request<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = Query> extends http.IncomingMessage, Express.Request {
|
||||
/**
|
||||
* Return request header.
|
||||
*
|
||||
@ -463,7 +467,7 @@ export interface Request<P extends Params = ParamsDictionary, ResBody = any, Req
|
||||
|
||||
params: P;
|
||||
|
||||
query: any;
|
||||
query: ReqQuery;
|
||||
|
||||
route: any;
|
||||
|
||||
|
||||
@ -168,6 +168,17 @@ namespace express_tests {
|
||||
// Params cannot be a custom type that does not conform to constraint
|
||||
router.get<{ foo: number }>('/:foo', () => {}); // $ExpectError
|
||||
|
||||
// Query can be a custom type
|
||||
router.get('/:foo', (req: express.Request<{}, any, any , {q: string}>) => {
|
||||
req.query.q; // $ExpectType string
|
||||
req.query.a; // $ExpectError
|
||||
});
|
||||
|
||||
// Query will be defaulted to any
|
||||
router.get('/:foo', (req: express.Request<{}>) => {
|
||||
req.query; // $ExpectType Query
|
||||
});
|
||||
|
||||
// Response will default to any type
|
||||
router.get("/", (req: Request, res: express.Response) => {
|
||||
res.json({});
|
||||
|
||||
2
types/express/index.d.ts
vendored
2
types/express/index.d.ts
vendored
@ -104,7 +104,7 @@ declare namespace e {
|
||||
interface IRouterMatcher<T> extends core.IRouterMatcher<T> { }
|
||||
interface MediaType extends core.MediaType { }
|
||||
interface NextFunction extends core.NextFunction { }
|
||||
interface Request<P extends core.Params = core.ParamsDictionary> extends core.Request<P> { }
|
||||
interface Request<P extends core.Params = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = core.Query> extends core.Request<P, ResBody, ReqBody, ReqQuery> { }
|
||||
interface RequestHandler<P extends core.Params = core.ParamsDictionary> extends core.RequestHandler<P> { }
|
||||
interface RequestParamHandler extends core.RequestParamHandler { }
|
||||
export interface Response<ResBody = any> extends core.Response<ResBody> { }
|
||||
|
||||
@ -41,5 +41,5 @@ storage.getSanitizedFileName('IMAGE.jpg'); // $ExpectType string
|
||||
|
||||
storage.exists('tmp/123456.jpg', '/'); // $ExpectType Promise<boolean>
|
||||
storage.save(image, '/'); // $ExpectType Promise<string>
|
||||
storage.serve(); // $ExpectType (req: Request<ParamsDictionary>, res: Response<any>, next: NextFunction) => void
|
||||
storage.serve(); // $ExpectType (req: Request<ParamsDictionary, any, any, Query>, res: Response<any>, next: NextFunction) => void
|
||||
storage.delete('tmp/123456.jpg', '/'); // $ExpectType Promise<boolean>
|
||||
|
||||
@ -33,7 +33,7 @@ opts.jwtFromRequest = ExtractJwt.fromUrlQueryParameter('param_name');
|
||||
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('param_name');
|
||||
opts.jwtFromRequest = ExtractJwt.fromExtractors([ExtractJwt.fromHeader('x-api-key'), ExtractJwt.fromBodyField('field_name'), ExtractJwt.fromUrlQueryParameter('param_name')]);
|
||||
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
|
||||
opts.jwtFromRequest = (req: Request) => { return req.query.token; };
|
||||
opts.jwtFromRequest = (req: Request) => { return req.query.token as string; };
|
||||
opts.secretOrKey = new Buffer('secret');
|
||||
|
||||
declare function findUser(condition: {id: string}, callback: (error: any, user :any) => void): void;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user