If you know how to fix the issue, make a pull request instead.
@types/next package and had problems.Definitions by: in index.d.ts) so they can respond.If you do not mention the authors the issue will be ignored.
query and params are missing on the NextContext req even though they are present, i assume the IncomingMessage needs to be extended for this? If this is correct i can create a PR for this
I believe next.js is supposed to be pluggable with any server framework so it refers to the req as an http.IncomingMessage. Express enhances the req object with fields like params and query but they might not exist when using some other framework.
@dru89 @brikou @abraxxas @jthegedus @resir014 @scottdj92 @joaovieira
Okay that makes sense somewhat. I assume adding properties potentially added by other frameworks as optional is out of the question as it would clutter the type too much?
Yeah I think that would get slippery.
You could extend the NextContext interface yourself though --
interface ExpressNextContext extends NextContext {
req?: express.Request;
res?: express.Response;
}
class Page extends React.Component {
static getInitialProps(ctx: ExpressNextContext) {
...
Yeah i thought of that, it's just that i wasn't sure if that shouldnt be part of the type definitions themselves, but if there are so many different versions for the different backends it doesn't really make sense i guess.
I Assume this is the same "problem" for the Error object in the custom error page. In the next docs https://nextjs.org/docs/#custom-error-handling you try to access a statusCode property of the Error object, which also isn't there according to type definitions. So in general there are some cases where you need to extend existing definitions based on the backend you are using?
NextContext takes in a generic: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/dab682e6f807cc326e13494c34805fa461b4742e/types/next/index.d.ts#L32
Is this what you were looking for?
import { Request } from "express";
class Page extends React.Component {
public static getInitialProps(ctx: NextContext<Request>) {
...
}
OMG, how did i miss that?! Thanks a ton man, now everything makes so much more sense. I feared i had to extend all the types based on the backend i am using
We also create our own NextContext that extends the base one with the Express' Request and Response types as @ajliv mentioned.
@scottdj92 that is just typing the query object. Does not change the type of req/req and, thus, wouldn't allow you to use req.get('header') or res.redirect('url') for example. But sometimes that's all you need.
@scottdj92 that does not seem to work. Your example yields the following error:
Type 'Request' does not satisfy the constraint 'Record<string, string | string[] | undefined>'.
Index signature is missing in type 'Request'.
So i guess i will still have to extend them as suggested by @ajliv . But thanks for the clarification
statusCode is in http.OutgoingMessage, so res.statusCode should type check correctly. err.statusCode is your own app specific error, that your backend throws or passes to nextApp.renderError().
@joaovieira Yeah the statusCode for res is no problem, but error in NextContext ist typed as normal error without Statuscode, do you also simply overwrite this in your extended type?
Yes, or with an explicit cast where you need it.
interface MyError extends Error {
statusCode?: number;
}
class ErrorPage extends Component<ErrorPageProps> {
static getInitialProps(context: NextContext) {
const { err, req, res } = context;
const error: MyError = err;
// do something with error.statusCode.. or.. (err as MyError).statusCode
}
}
Okay, i was thinking about doing something like this. But i somehow expected it to be in the types if it is used in the documentation, that's why i was confused. But it seems then this is not really an issue with the types at all if that's the intended way to use them. Thank a lot for clearing up this confusion for me
Hi @scottdj92,
I am getting the same error as @abraxxas (below). Do you have any idea how to solve this?
I'd really like to use your approach since it seems as the cleanest one. <3
@scottdj92 that does not seem to work. Your example yields the following error:
Type 'Request' does not satisfy the constraint 'Record<string, string | string[] | undefined>'. Index signature is missing in type 'Request'.
@cJayyy what i did in the end was to extend it manually like this
export interface ExpressNextContext<Q extends DefaultQuery = DefaultQuery> extends NextContext<Q> {
req?: Request
res?: Response
store: Store<AppState, any>
}
@abraxxas Thx for instant reply. Could you please also specify the source of DefaultQuery?
@cJayyy defaultQuery can be imported from next/router import { DefaultQuery } from 'next/router'
Thanks!
Although this approach isn't as clean as @scottdj92 's, it offers much more complexity. 馃憤
I ended up enhancing NextContext like this
_models_
import { NextContext } from 'next';
import { DefaultQuery } from 'next/router';
import { Request, Response } from 'express';
export interface AppContext<Q extends DefaultQuery = DefaultQuery> extends NextContext<Q> {
req?: Request;
res?: Response;
err?: { statusCode?: number } & Error;
store: Store<State, any>;
}
_error page_
interface ErrorPageProps {
statusCode?: number;
}
const ErrorPage: NextFunctionComponent<ErrorPageProps, ErrorPageProps, AppContext> = ({ statusCode }) => (
<p>
Error {statusCode ? statusCode : null}
</p>
);
ErrorPage.getInitialProps = ({ res, err }: AppContext) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : undefined;
return { statusCode };
};
Most helpful comment
Yeah I think that would get slippery.
You could extend the NextContext interface yourself though --