From b141f33f6698e4128ea979146c585ec7c4ca482d Mon Sep 17 00:00:00 2001 From: Kevin Welcher Date: Fri, 10 Aug 2018 19:05:29 -0400 Subject: [PATCH 1/4] Adds generic Query parameter to next.js's router --- types/next/router.d.ts | 30 ++++++++++++++------------- types/next/test/next-router-tests.tsx | 10 +++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/types/next/router.d.ts b/types/next/router.d.ts index fe3563d473..3072455e45 100644 --- a/types/next/router.d.ts +++ b/types/next/router.d.ts @@ -26,20 +26,22 @@ export type PopStateCallback = (state: any) => boolean | undefined; export type RouterCallback = () => void; -export interface RouterProps { +interface DefaultQuery { + [key: string]: + | boolean + | boolean[] + | number + | number[] + | string + | string[]; +} + +export interface RouterProps { // url property fields readonly pathname: string; readonly route: string; readonly asPath?: string; - readonly query?: { - [key: string]: - | boolean - | boolean[] - | number - | number[] - | string - | string[]; - }; + readonly query?: Q; // property fields readonly components: { @@ -78,14 +80,14 @@ export interface RouterProps { }; } -export interface SingletonRouter extends RouterProps { - router: RouterProps | null; +export interface SingletonRouter extends RouterProps { + router: RouterProps | null; readyCallbacks: RouterCallback[]; ready(cb: RouterCallback): void; } -export interface WithRouterProps { - router: SingletonRouter; +export interface WithRouterProps { + router: SingletonRouter; } export function withRouter( diff --git a/types/next/test/next-router-tests.tsx b/types/next/test/next-router-tests.tsx index fdcf1de3ff..04fa50b912 100644 --- a/types/next/test/next-router-tests.tsx +++ b/types/next/test/next-router-tests.tsx @@ -96,3 +96,13 @@ class TestComponent extends React.Component { } + +const TestSFC: React.SFC = ({ router }) => { + return
{router.query && router.query.test}
; +}; From dbd0352e7bdfbf38360135df8c77b7f2acf533ff Mon Sep 17 00:00:00 2001 From: Kevin Welcher Date: Mon, 13 Aug 2018 09:52:13 -0400 Subject: [PATCH 2/4] Adds tslint ignore rule --- types/next/router.d.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/types/next/router.d.ts b/types/next/router.d.ts index 3072455e45..2b019625f6 100644 --- a/types/next/router.d.ts +++ b/types/next/router.d.ts @@ -90,8 +90,12 @@ export interface WithRouterProps { router: SingletonRouter; } -export function withRouter( - Component: React.ComponentType, +// Manually disabling the no-unnecessary-generics rule so users can +// retain type inference if they warp their component in withRouter +// without defining props explicitly +export function withRouter( + // tslint:disable-next-line:no-unnecessary-generics + Component: React.ComponentType>, ): React.ComponentType; declare const Router: SingletonRouter; From 327d5763a6384606f6827634b6efcd5bc018733b Mon Sep 17 00:00:00 2001 From: Kevin Welcher Date: Mon, 13 Aug 2018 09:57:11 -0400 Subject: [PATCH 3/4] Adds generic query param to next context as well --- types/next/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/next/index.d.ts b/types/next/index.d.ts index 2d87121d61..af4d26aa7f 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -24,11 +24,11 @@ declare namespace next { * Context object used in methods like `getInitialProps()` * <> */ - interface NextContext { + interface NextContext { /** path section of URL */ pathname: string; /** query string section of URL parsed as an object */ - query: QueryStringMapObject; + query: Q; /** String of the actual path (including the query) shows in the browser */ asPath: string; /** HTTP request object (server only) */ From bdf3eeeae8ba9fcf808de764e3af40a359c8b445 Mon Sep 17 00:00:00 2001 From: Kevin Welcher Date: Mon, 13 Aug 2018 15:55:05 -0400 Subject: [PATCH 4/4] Adds query to other cross cutting interfaces --- types/next/app.d.ts | 16 ++++++++-------- types/next/index.d.ts | 6 +++--- types/next/router.d.ts | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/types/next/app.d.ts b/types/next/app.d.ts index e086af0ca8..d077c0e95a 100644 --- a/types/next/app.d.ts +++ b/types/next/app.d.ts @@ -1,19 +1,19 @@ import * as React from "react"; import { NextContext } from "."; -import { RouterProps } from "./router"; +import { RouterProps, DefaultQuery } from "./router"; -export interface AppComponentProps { +export interface AppComponentProps { Component: React.ComponentType; - router: RouterProps; + router: RouterProps; pageProps: any; } -export interface AppComponentContext { +export interface AppComponentContext { Component: React.ComponentType; - router: RouterProps; - ctx: NextContext; + router: RouterProps; + ctx: NextContext; } -export class Container extends React.Component {} +export class Container extends React.Component { } -export default class App extends React.Component {} +export default class App extends React.Component> { } diff --git a/types/next/index.d.ts b/types/next/index.d.ts index af4d26aa7f..71d769ed31 100644 --- a/types/next/index.d.ts +++ b/types/next/index.d.ts @@ -43,10 +43,10 @@ declare namespace next { isServer?: boolean; } - type NextSFC = NextStatelessComponent; - interface NextStatelessComponent + type NextSFC = NextStatelessComponent; + interface NextStatelessComponent extends React.StatelessComponent { - getInitialProps?: (ctx: NextContext) => Promise; + getInitialProps?: (ctx: NextContext) => Promise; } type UrlLike = url.UrlObject | url.Url; diff --git a/types/next/router.d.ts b/types/next/router.d.ts index 2b019625f6..be3665e3d5 100644 --- a/types/next/router.d.ts +++ b/types/next/router.d.ts @@ -26,7 +26,7 @@ export type PopStateCallback = (state: any) => boolean | undefined; export type RouterCallback = () => void; -interface DefaultQuery { +export interface DefaultQuery { [key: string]: | boolean | boolean[]