Skip to content

Commit

Permalink
Enable strict mode for TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
hswolff committed Aug 2, 2020
1 parent 58c542b commit 9a23348
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 32 deletions.
8 changes: 5 additions & 3 deletions components/content.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
function Item({ item }) {
import ItemInterface from 'data/data-types';

function Item({ item }: { item: ItemInterface }) {
return (
<div className="border border-gray-400 rounded-md shadow my-8 p-4 flex flex-col sm:flex-row hover:border-gray-500 ease-linear transition duration-150">
<div className="mx-auto pr-4 text-center">
<div className="text-4xl align-top sm:-mt-1">⬆️</div>
<div className="border border-blue-800 bg-blue-300 rounded max-">
{item.votes}
{item.votes.length}
</div>
</div>
<div className="content flex-grow">
Expand All @@ -19,7 +21,7 @@ function Item({ item }) {
);
}

export default function Content({ items }) {
export default function Content({ items }: { items: ItemInterface[] }) {
return (
<ul className="container mx-auto my-2 max-w-6xl">
{items.map((item) => (
Expand Down
3 changes: 2 additions & 1 deletion components/sign-in.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useSession } from 'next-auth/client';
import { signin, signout } from 'next-auth/client';

// @ts-expect-error
function ExampleSession({ session }) {
return (
<p>
Expand Down Expand Up @@ -29,7 +30,7 @@ export default function SignIn() {
<div>{session ? `Welcome ${session.user.name}` : null}</div>
<div>
{session ? (
<button onClick={signout}>Sign out</button>
<button onClick={() => signout()}>Sign out</button>
) : (
<button onClick={() => signin('github')}>Sign in</button>
)}
Expand Down
24 changes: 24 additions & 0 deletions data/data-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
type ObjectId = string;

export enum ItemCategory {
Tutorial = 'Tutorial',
Opinion = 'Opinion',
Vlog = 'Vlog',
}

export interface ItemVote {
userId: ObjectId;
created: Date;
}

export default interface Item {
_id: ObjectId;
title: string;
description: string;
created: Date;
updated: Date;
category: ItemCategory;
createdBy: ObjectId;
status: 'open' | 'accepted' | 'declined' | 'completed';
votes: ItemVote[];
}
21 changes: 14 additions & 7 deletions hooks/api-hooks.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useQuery, useMutation, queryCache } from 'react-query';
import Item from 'data/data-types';

export function useItems() {
return useQuery('items', () => fetch('/api/items').then((res) => res.json()));
return useQuery<Item[], unknown, string>('items', () =>
fetch('/api/items').then((res) => res.json())
);
}

const addItem = (body) => {
const addItem = (body: Partial<Item>) => {
return fetch('/api/items', {
method: 'POST',
body: JSON.stringify(body),
Expand All @@ -20,9 +23,13 @@ export function useAddItem() {
}

export function useClearItems() {
return useMutation(() => fetch('/api/items', { method: 'DELETE' }), {
onSuccess() {
queryCache.invalidateQueries('items');
},
});
return useMutation(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(e_: unknown) => fetch('/api/items', { method: 'DELETE' }),
{
onSuccess() {
queryCache.invalidateQueries('items');
},
}
);
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"tailwindcss": "^1.6.0"
},
"devDependencies": {
"@types/faker": "^4.1.12",
"@types/node": "^14.0.27",
"@types/react": "^16.9.43",
"@typescript-eslint/eslint-plugin": "^3.7.1",
Expand Down
4 changes: 3 additions & 1 deletion pages/_app.js → pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import '../styles/tailwind.css';
import type { AppProps } from 'next/app';
// @ts-expect-error
import { Provider } from 'next-auth/client';

function MyApp({ Component, pageProps }) {
function MyApp({ Component, pageProps }: AppProps) {
const { session } = pageProps;
return (
<Provider options={{ site: process.env.SITE }} session={session}>
Expand Down
2 changes: 1 addition & 1 deletion pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const options = {
}),
],

// database: process.env.DATABASE_URL,
// database: process.env.DATABASE_URL,
};

export default (req, res) => NextAuth(req, res, options);
6 changes: 0 additions & 6 deletions pages/api/hello.ts

This file was deleted.

23 changes: 12 additions & 11 deletions pages/api/items.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
import { NextApiRequest, NextApiResponse } from 'next';

import faker from 'faker';
import Item, { ItemCategory } from 'data/data-types';

faker.seed(1);

function generateItem({ title = null, description = null } = {}) {
function generateItem({ title = null, description = null } = {}): Item {
return {
_id: faker.random.uuid(),
title: title ?? faker.lorem.words(),
description: description ?? faker.lorem.paragraph(),
created: faker.date.past().toUTCString(),
updated: faker.date.past().toUTCString(),
category: faker.random.arrayElement(['Tutorial', 'Opinion', 'Vlog']),
created: faker.date.past(),
updated: faker.date.past(),
category: faker.random.arrayElement([
ItemCategory.Tutorial,
ItemCategory.Opinion,
ItemCategory.Vlog,
]),
createdBy: faker.random.uuid(),
status: faker.random.arrayElement([
'open',
'accepted',
'declined',
'completed',
]),
votes: faker.random.number(100),
// votes: {
// up: [],
// down: [],
// },
votes: [],
};
}

let postRequests = [];
let postRequests: Item[] = [];

export default (req: NextApiRequest, res: NextApiResponse) => {
const items = postRequests
// @ts-expect-error
.concat([...Array(10).keys()])
// @ts-ignore
.map((item) => generateItem(typeof item === 'number' ? undefined : item));

if (req.method === 'GET') {
Expand Down
2 changes: 1 addition & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function Home() {

<SignIn />
<AddItemForm />
{isSuccess && <Content items={data} />}
{isSuccess && data && <Content items={data} />}
</div>
);
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"strict": true,
"typeRoots": ["./typings", "./node_modules/@types"],
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
Expand Down
85 changes: 85 additions & 0 deletions typings/next-auth.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// source: https://github.com/nextauthjs/next-auth/pull/220
declare module 'next-auth/client' {
// Minimum TypeScript Version: 3.8
import { IncomingMessage } from 'http';

interface Session {
user: {
name: string;
email: string;
image: string;
};
accessToken: string;
expires: string;
}

interface GetProvidersResponse {
[provider: string]: Provider;
}

interface Provider {
id: string;
name: string;
type: string;
signinUrl: string;
callbackUrl: string;
}

interface GenericObject {
[key: string]: any;
}

declare function useSession(): [Session, boolean];
declare function getSession(context: NextContext): Promise<Session | null>;
declare function session(context: NextContext): Promise<Session | null>;
declare function getProviders(
context: NextContext
): Promise<GetProvidersResponse | null>;
declare function providers(
context: NextContext
): Promise<GetProvidersResponse | null>;
declare function getCsrfToken(context: NextContext): Promise<string | null>;
declare function csrfToken(context: NextContext): Promise<string | null>;
declare function signin(
provider: Provider | string,
data?: GenericObject
): Promise<void>;
declare function signout(context?: NextContext): Promise<void>;

export {
useSession,
getSession,
session,
getProviders,
providers,
getCsrfToken,
csrfToken,
signin,
signout,
};
export type { Session };

/**
* TODO: `dtslint` throws when parsing Next types... the following types are copied directly from `next/types` ...
* @see https://github.com/microsoft/dtslint/issues/297
*/

interface NextApiRequest extends IncomingMessage {
query: {
[key: string]: string | string[];
};
cookies: {
[key: string]: string;
};
body: any;
env: Env;
}

interface NextContext {
req: NextApiRequest;
}

interface Env {
[key: string]: string;
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,11 @@
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==

"@types/faker@^4.1.12":
version "4.1.12"
resolved "https://registry.yarnpkg.com/@types/faker/-/faker-4.1.12.tgz#065d37343677df1aa757c622650bd14666c42602"
integrity sha512-0MEyzJrLLs1WaOCx9ULK6FzdCSj2EuxdSP9kvuxxdBEGujZYUOZ4vkPXdgu3dhyg/pOdn7VCatelYX7k0YShlA==

"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
version "7.0.5"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
Expand Down

0 comments on commit 9a23348

Please sign in to comment.