After upgrading from Next 8.1.0 to 8.1.1 Canary the typescript type definition for WithRouterProps is not there anymore. In the previous version the following statement worked.
import { withRouter, WithRouterProps } from 'next/router';
During the 8.1.1 Canary development iteration withRouter was changed a bit. What is the approach to get those types back again.
You were probably using @types/next which is not part of Next.js core and community maintained, it does not reflect the types that we want to provide out of the box.
I'm seeing this as well with 8.1.1-canary.28. LinkProps from next/link and WithRouterProps from next/router don't seem to be exported. I removed @types/next from my devDependencies and the error messages confirm that the typings are coming from the next module directly. Could this issue please be reopened?
Module '"./myproject/node_modules/next/router"' has no exported member 'WithRouterProps'.
Module '"./myproject/node_modules/next/link"' has no exported member 'LinkProps'.
As said withRouterProps is not a thing. @types/next doesn't reflect the Next.js core, it's community maintained and the maintainer of those types invented names.
I was able to update to use the new typings and wanted to share my solutions:
My component that was being wrapped by withRouter was previously typed with React.FC<WithRouterProps>. I've updated its type to be React.FC<{router: PublicRouterInstance}>, where PublicRouterInstance is a type imported from next/router.
I was using LinkProps in the props definition for a component that wrapped Link, and extended the Link interface to accept additional props. My interface was something like interface Props extends LinkProps { ...}. This is now working using interface Props extends React.ComponentPropsWithoutRef<typeof Link> {...}. It's a little more verbose, so I think there would be some value in exporting a props interface for Link (and other components) to support this pattern.
If there is a better way to achieve these things, I'd be interesting in learning about them.
The same problem with LinkProps after updating to canary.
Do I understand correctly that PR with add only export here will be rejected?
@ahutchings guidance worked for me. however i think withRouterProps probably ought to be exported too.
however, assuming this proposal is not accepted, there's a minor type issue with getInitialProps on React.FC. i solved it this way:
import axios from "axios"
import Link from "next/link"
import Head from "next/head"
import { withRouter, PublicRouterInstance } from "next/router"
type Type = React.FC<{ router: PublicRouterInstance; posts: any }> & { getInitialProps: any }
const Home: Type = ({ posts }) => {
return (
<div>
<Head>
<title>Next on Netlify</title>
</Head>
{posts.map((post) => (
<div key={post.id}>
<Link href={`/post?id=${post.id}`} as={`/posts/${post.id}`} passHref>
<a>{post.title}</a>
</Link>
</div>
))}
</div>
)
}
Home.getInitialProps = async (props) => {
if (props.res) {
console.log("setHeader")
props.res.setHeader("Cache-Control", "public, s-maxage=30, stale-while-revalidate")
}
console.log(props.asPath, props.query)
const { data } = await axios.get("https://netlify-json-api.netlify.com/posts")
return { posts: data }
}
export default withRouter(Home)
The file:
\node_modules\next\dist\client\with-router.d.ts
contains the WithRouterProps type!
But why can't it be imported?
import {WithRouterProps} from 'next/router';
Cannot find module next/client/with-router
import { WithRouterProps} from 'next/client/with-router';
@khusamov
for now you can do
import { WithRouterProps } from "next/dist/client/with-router";
Would love to have WithRouterProps exported from next/router
Please open any requests as new issues, as it's really hard to track comments on closed issues.
Most helpful comment
I was able to update to use the new typings and wanted to share my solutions:
My component that was being wrapped by
withRouterwas previously typed withReact.FC<WithRouterProps>. I've updated its type to beReact.FC<{router: PublicRouterInstance}>, wherePublicRouterInstanceis a type imported fromnext/router.I was using
LinkPropsin the props definition for a component that wrappedLink, and extended the Link interface to accept additional props. My interface was something likeinterface Props extends LinkProps { ...}. This is now working usinginterface Props extends React.ComponentPropsWithoutRef<typeof Link> {...}. It's a little more verbose, so I think there would be some value in exporting a props interface for Link (and other components) to support this pattern.If there is a better way to achieve these things, I'd be interesting in learning about them.