From 7c3ea5431519b9a5850b65a3bad088a86455755d Mon Sep 17 00:00:00 2001 From: David Paul Graham <43794491+dpgraham4401@users.noreply.github.com> Date: Tue, 11 Jun 2024 20:19:06 -0400 Subject: [PATCH] Typescript eslint (#141) * update eslint config to use typescript-eslint/recommended-type-checked and detect react version * update tsconfig to reflect updates to eslint config * fix eslint errors * fix unused ts-expect-error --- .eslintrc.cjs | 11 ++++++++++- __mocks__/zustand.ts | 1 - src/App.spec.tsx | 4 ++-- src/components/Help/Help.spec.tsx | 2 ++ src/hooks/useFetchConfig/useFetchConfig.spec.tsx | 2 +- src/hooks/useFetchConfig/useFetchConfig.tsx | 2 +- src/hooks/useFetchHelp/useFetchHelp.spec.tsx | 4 +++- src/hooks/useFetchHelp/useFetchHelp.tsx | 15 +++++++++------ src/hooks/useUrl/useUrl.spec.tsx | 4 ++-- src/hooks/useUrl/useUrl.tsx | 2 +- tsconfig.json | 3 --- 11 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 97480e5..26c9220 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,7 +4,7 @@ module.exports = { extends: [ 'eslint:recommended', 'plugin:react/recommended', - 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-type-checked', 'plugin:react-hooks/recommended', 'plugin:prettier/recommended', 'plugin:jsx-a11y/recommended', @@ -12,10 +12,19 @@ module.exports = { ], ignorePatterns: ['dist', '.eslintrc.cjs'], parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, plugins: ['react-refresh', 'react', 'prettier'], rules: { 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], 'react/react-in-jsx-scope': 'off', 'react/jsx-uses-react': 'off', }, + settings: { + react: { + version: 'detect', + }, + }, }; diff --git a/__mocks__/zustand.ts b/__mocks__/zustand.ts index 62ae171..e81c53c 100644 --- a/__mocks__/zustand.ts +++ b/__mocks__/zustand.ts @@ -10,7 +10,6 @@ const { create: actualCreate, createStore: actualCreateStore } = // @ts-expect-error - import the actual zustand module await vi.importActual('zustand'); -// @ts-expect-error - a variable to hold reset functions for all stores declared in the app export const storeResetFns = new Set<() => void>(); const createUncurried = (stateCreator: zustand.StateCreator) => { diff --git a/src/App.spec.tsx b/src/App.spec.tsx index 963e4c4..9945785 100644 --- a/src/App.spec.tsx +++ b/src/App.spec.tsx @@ -19,7 +19,7 @@ const TestComponent = () => { }; const handlers = [ - http.get('/default.json', async () => { + http.get('/default.json', () => { return HttpResponse.json({ nodes: [ { @@ -88,7 +88,7 @@ describe('App', () => { expect(screen.getByTestId(/minimap/i)).toBeInTheDocument(); }); test('Throws an error if there is an error fetching the config', async () => { - server.use(http.get('/default.json', async () => HttpResponse.error())); + server.use(http.get('/default.json', () => HttpResponse.error())); renderWithProviders(); await waitFor(() => expect(screen.queryByTestId('spinner')).not.toBeInTheDocument()); expect(screen.getByText(/Error/i)).toBeInTheDocument(); diff --git a/src/components/Help/Help.spec.tsx b/src/components/Help/Help.spec.tsx index 44b28de..9c54560 100644 --- a/src/components/Help/Help.spec.tsx +++ b/src/components/Help/Help.spec.tsx @@ -14,11 +14,13 @@ const handlers = [ return HttpResponse.json({ type: 'text', + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions content: `Help Text ${helpId}`, }); }), http.get('/help/:helpId.html', (info) => { const helpId = info.params.helpId; + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions return HttpResponse.text(`

Help html ${helpId}

`); }), ]; diff --git a/src/hooks/useFetchConfig/useFetchConfig.spec.tsx b/src/hooks/useFetchConfig/useFetchConfig.spec.tsx index e816777..411a216 100644 --- a/src/hooks/useFetchConfig/useFetchConfig.spec.tsx +++ b/src/hooks/useFetchConfig/useFetchConfig.spec.tsx @@ -55,7 +55,7 @@ const TestComponent = () => { ); }; -describe('useFetchConfig', async () => { +describe('useFetchConfig', () => { test('initially isLoading, error, and data are undefined', () => { render(); expect(screen.queryByText(/error/i)).not.toBeInTheDocument(); diff --git a/src/hooks/useFetchConfig/useFetchConfig.tsx b/src/hooks/useFetchConfig/useFetchConfig.tsx index 445c3f3..3302dbf 100644 --- a/src/hooks/useFetchConfig/useFetchConfig.tsx +++ b/src/hooks/useFetchConfig/useFetchConfig.tsx @@ -76,7 +76,7 @@ export const useFetchConfig = (configPath: string) => { setConfig(undefined); setError(undefined); fetch(configPath) - .then((response) => response.json()) + .then((response) => response.json() as Promise) .then((data) => { try { const config = parseConfig(data); diff --git a/src/hooks/useFetchHelp/useFetchHelp.spec.tsx b/src/hooks/useFetchHelp/useFetchHelp.spec.tsx index ba1439c..540f2a5 100644 --- a/src/hooks/useFetchHelp/useFetchHelp.spec.tsx +++ b/src/hooks/useFetchHelp/useFetchHelp.spec.tsx @@ -12,6 +12,7 @@ const handlers = [ nodes: [ { type: 'text', + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions content: `Help Text ${nodeId}`, }, ], @@ -19,6 +20,7 @@ const handlers = [ }), http.get('/help/:nodeId.html', (info) => { const nodeId = info.params.nodeId; + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions return HttpResponse.text(`

Help Text ${nodeId}

`); }), ]; @@ -32,7 +34,7 @@ afterEach(() => { beforeAll(() => server.listen()); afterAll(() => server.close()); -describe('useFetchHelp', async () => { +describe('useFetchHelp', () => { test('error, help are initially falsy, isLoading is truthy', () => { const { result } = renderHook(() => useFetchHelp('foo.json')); expect(result.current.error).toBeFalsy(); diff --git a/src/hooks/useFetchHelp/useFetchHelp.tsx b/src/hooks/useFetchHelp/useFetchHelp.tsx index 54b7096..ff2bceb 100644 --- a/src/hooks/useFetchHelp/useFetchHelp.tsx +++ b/src/hooks/useFetchHelp/useFetchHelp.tsx @@ -8,7 +8,7 @@ export type HelpConfig = HelpContent; export const useFetchHelp = (fileName?: string) => { const [help, setHelp] = useState(); const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(); + const [error, setError] = useState(); useEffect(() => { setIsLoading(true); @@ -34,21 +34,24 @@ export const useFetchHelp = (fileName?: string) => { }) .then((data) => { if (fileName.endsWith('.json')) { - data = { + const help: HelpContent = { type: 'text', + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access content: data.content, }; + setHelp(help); } else { - data = { + const help: HelpContent = { type: 'html', + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment content: data, }; + setHelp(help); } - setHelp(data); setIsLoading(false); }) - .catch((e) => { - setError(e); + .catch((e: Error) => { + setError(e.message); setIsLoading(false); }); }, [fileName]); diff --git a/src/hooks/useUrl/useUrl.spec.tsx b/src/hooks/useUrl/useUrl.spec.tsx index 4476a5e..1622f6f 100644 --- a/src/hooks/useUrl/useUrl.spec.tsx +++ b/src/hooks/useUrl/useUrl.spec.tsx @@ -21,10 +21,10 @@ suite('useUrl hook', () => { const { result } = renderHook(() => useUrl(), { wrapper }); expect(result.current.pathParam).toBe(pathQueryParam); }); - test('returns the path URL query param', async () => { + test('returns the path URL query param', () => { const pathQueryParam = 'foo'; const { result } = renderHook(() => useUrl(), { wrapper }); - await act(async () => { + act(() => { result.current.setPathParam(pathQueryParam); }); expect(result.current.pathParam).toBe(pathQueryParam); diff --git a/src/hooks/useUrl/useUrl.tsx b/src/hooks/useUrl/useUrl.tsx index 7f68938..b6d80ed 100644 --- a/src/hooks/useUrl/useUrl.tsx +++ b/src/hooks/useUrl/useUrl.tsx @@ -27,7 +27,7 @@ export const useUrl = () => { const copyUrl = () => { if (path.length < 1) return; setUrlPathId(path[path.length - 1].selected); - navigator.clipboard + void navigator.clipboard .writeText(window.location.href) .then(() => window.alert('URL copied to clipboard')); }; diff --git a/tsconfig.json b/tsconfig.json index 8e30641..bfcea4f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,9 +22,6 @@ "jsx": "react-jsx", "incremental": true }, - "include": [ - "src" - ], "exclude": [ "node_modules", "build"