From 04f5554ff598053f896ebaf27304f09e5f156bc8 Mon Sep 17 00:00:00 2001 From: Rico Kahler Date: Sun, 3 Jan 2021 19:14:47 -0500 Subject: [PATCH] feat: is server side context type guard (#19) * feat: is server side context type guard * update readme * Update README.md --- README.md | 27 +++++++++++++++++++++++- package-lock.json | 2 +- package.json | 2 +- src/index.ts | 1 + src/is-server-side-props-context.test.ts | 6 ++++++ src/is-server-side-props-context.ts | 14 ++++++++++++ 6 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/is-server-side-props-context.test.ts create mode 100644 src/is-server-side-props-context.ts diff --git a/README.md b/README.md index a0cc440f..f255494b 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,31 @@ const useBlogPost = createDataHook('BlogPost', async (context) => { export default useBlogPost; ``` +
+ +TypeScript User? + +> Note: For TypeScript users, if you're planning on only using the data hook in the context of `getServerSideProps`, you can import the provided [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards), `isServerSidePropsContext`, to narrow the type of the incoming context. + + + +```tsx +import { createDataHook, isServerSidePropsContext } from 'next-data-hooks'; + +const useServerSideData = createDataHook('Data', async (context) => { + if (!isServerSidePropsContext(context)) { + throw new Error('This data hook only works in getServerSideProps.'); + } + + // here, the type of `context` has been narrowed to the server side conext + const query = context.req.query; +}); + +export default useServerSideData; +``` + +
+ 2. Use the data hook in a component. Add it to a static prop in an array with other data hooks to compose them downward. ```tsx @@ -135,7 +160,7 @@ BlogPostComponent.dataHooks = [ export default BlogPostComponent; ``` -3. Pass the data hooks down in `getStaticProps`. +3. Pass the data hooks down in `getStaticProps` or `getServerSideProps`. ```tsx import { getDataHooksProps } from 'next-data-hooks'; diff --git a/package-lock.json b/package-lock.json index 9e6bacac..ff8bfc35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "next-data-hooks", - "version": "0.4.0", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 07bffb17..cc9f3649 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next-data-hooks", - "version": "0.4.0", + "version": "0.5.0", "description": "Use `getStaticProps` as react hooks", "private": true, "scripts": { diff --git a/src/index.ts b/src/index.ts index 8b7b9ea0..fef97a2b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,4 @@ export { default as createDataHook } from './create-data-hook'; export { default as getDataHooksProps } from './get-data-hooks-props'; export { default as NextDataHooksContext } from './next-data-hooks-context'; export { default as NextDataHooksProvider } from './next-data-hooks-provider'; +export { default as isServerSidePropsContext } from './is-server-side-props-context'; diff --git a/src/is-server-side-props-context.test.ts b/src/is-server-side-props-context.test.ts new file mode 100644 index 00000000..88364457 --- /dev/null +++ b/src/is-server-side-props-context.test.ts @@ -0,0 +1,6 @@ +import isServerSidePropsContext from './is-server-side-props-context'; + +it('returns true if there is a req and res', () => { + expect(isServerSidePropsContext({ req: true, res: true } as any)).toBe(true); + expect(isServerSidePropsContext({} as any)).toBe(false); +}); diff --git a/src/is-server-side-props-context.ts b/src/is-server-side-props-context.ts new file mode 100644 index 00000000..e89740a0 --- /dev/null +++ b/src/is-server-side-props-context.ts @@ -0,0 +1,14 @@ +import { GetServerSidePropsContext, GetStaticPropsContext } from 'next'; + +function isServerSidePropsContext( + context: GetServerSidePropsContext | GetStaticPropsContext +): context is GetServerSidePropsContext { + if (typeof context !== 'object' || !context) return false; + + return ( + !!(context as GetServerSidePropsContext).req && + !!(context as GetServerSidePropsContext).res + ); +} + +export default isServerSidePropsContext;