refactor: enable typescript-eslint strict rules (#243)

This commit is contained in:
Marco Pasqualetti
2024-12-22 12:08:21 +01:00
committed by GitHub
parent de74647c43
commit 77e22c40b6
16 changed files with 57 additions and 36 deletions
+2
View File
@@ -8,6 +8,8 @@ dist/
examples/*/pnpm-lock.yaml
vite.config.ts.timestamp*
## Rust related ignores
# Generated by Cargo
@@ -64,7 +64,9 @@ export function TableOfContents({
),
)
window.addEventListener('scroll', handleScroll)
return (): void => window.removeEventListener('scroll', handleScroll)
return (): void => {
window.removeEventListener('scroll', handleScroll)
}
}, [router.pathname])
if (filteredHeadings.length === 0) {
@@ -17,9 +17,9 @@ export default function ThemeBtn(): JSX.Element {
return (
<ActionIcon
onClick={() =>
onClick={() => {
setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')
}
}}
variant="default"
size="lg"
aria-label="Toggle color scheme"
+22 -12
View File
@@ -25,10 +25,17 @@ export default tseslint.config(
reportUnusedDisableDirectives: 'error',
},
},
eslint.configs.recommended,
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access */
eslintPluginImport.flatConfigs.recommended,
eslintPluginImport.flatConfigs.typescript,
tseslint.configs.recommendedTypeChecked,
/* eslint-enable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access */
// eslint-disable-next-line import/no-named-as-default-member
tseslint.configs.strictTypeChecked,
{
languageOptions: {
parserOptions: {
@@ -50,16 +57,13 @@ export default tseslint.config(
rules: {
// #region @typescript-eslint
'@typescript-eslint/array-type': ['error', { default: 'generic' }],
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/no-empty-object-type': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'type-imports' },
],
'@typescript-eslint/explicit-module-boundary-types': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/method-signature-style': ['error', 'property'],
'@typescript-eslint/naming-convention': [
'error',
@@ -74,19 +78,24 @@ export default tseslint.config(
},
},
],
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-empty-function': 'error',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/no-inferrable-types': [
'error',
{ ignoreParameters: true },
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: true,
allowRegExp: false,
},
],
// #endregion @typescript-eslint
// #region import
@@ -127,6 +136,7 @@ export default tseslint.config(
'no-shadow': 'error',
'no-undef': 'off',
'sort-imports': 'off',
// #endregion misc
},
},
{
@@ -3,7 +3,7 @@ import type { RouteNode } from './types'
export function buildRouteConfig(nodes: Array<RouteNode>, depth = 1): string {
const children = nodes.map((node) => {
const route = `${node.variableName}Route`
const route = `${node.variableName as string}Route`
if (node.children?.length) {
const childConfigs = buildRouteConfig(node.children, depth + 1)
@@ -157,14 +157,14 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
(d): number => (d.routePath.includes(`/${ROOT_PATH_ID}`) ? -1 : 1),
(d): number => d.routePath.split('/').length,
(d): number => (d.routePath.endsWith("index'") ? -1 : 1),
(d): any => d,
(d): RouteNode => d,
])
const imports = [
...sortedRouteNodes.map((node) => {
const extension = node.filePath.endsWith('mdx') ? '.mdx' : ''
return `const ${
node.variableName
node.variableName as string
}Import = dynamic(() => import('./${replaceBackslash(
removeExt(
path.relative(
@@ -181,18 +181,21 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
...sortedRouteNodes.map((node) => {
const isRoot = node.routePath.endsWith(ROOT_PATH_ID)
const rootDeclaration = isRoot ? ', isRoot: true' : ''
const variableName = node.variableName as string
return `const ${node.variableName} = createRoute({ component: ${node.variableName}Import${rootDeclaration} })`
return `const ${variableName} = createRoute({ component: ${variableName}Import${rootDeclaration} })`
}),
].join('\n')
const createRouteUpdates = [
sortedRouteNodes
.map((node) => {
const variableName = node.variableName as string
const cleanedPath = node.cleanedPath as string
return [
`const ${node.variableName}Route = ${node.variableName}.update({
`const ${variableName}Route = ${variableName}.update({
${[
!node.path?.endsWith(ROOT_PATH_ID) && `path: '${node.cleanedPath}'`,
!node.path?.endsWith(ROOT_PATH_ID) && `path: '${cleanedPath}'`,
`getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,
rustHandlersNodes.includes(node.path || '')
? 'hasHandler: true'
@@ -236,7 +239,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
const routeTreeContent = await fsp
.readFile(path.resolve(config.generatedRouteTree), 'utf-8')
.catch((e) => {
.catch((e: unknown) => {
const err = e as Error & { code?: string }
if (err.code === 'ENOENT') {
return undefined
@@ -42,7 +42,7 @@ describe('Test RouteMatch component', () => {
test('It should correctly render nested routes', () => {
vi.mock('../hooks/useServerSideProps.tsx', () => ({
useServerSideProps: (): { data: any; isLoading: boolean } => {
useServerSideProps: (): { data: unknown; isLoading: boolean } => {
return {
data: undefined,
isLoading: false,
+6 -4
View File
@@ -1,9 +1,9 @@
import * as React from 'react'
import type { ReactElement, ComponentType } from 'react'
import type { ReactElement } from 'react'
import type { RouteComponent } from './types'
type ImportFn = () => Promise<{ default: React.ComponentType<any> }>
type ImportFn = () => Promise<{ default: RouteComponent }>
/**
* Helper function to lazy load any component.
@@ -44,7 +44,7 @@ export const dynamic = (importFn: ImportFn): React.JSX.Element => {
export const __tuono__internal__lazyLoadComponent = (
factory: ImportFn,
): RouteComponent => {
let LoadedComponent: ComponentType<any> | undefined
let LoadedComponent: RouteComponent | undefined
const LazyComponent = React.lazy(factory) as unknown as RouteComponent
const loadComponent = (): Promise<void> =>
@@ -52,7 +52,9 @@ export const __tuono__internal__lazyLoadComponent = (
LoadedComponent = module.default
})
const Component = (props: any): ReactElement =>
const Component = (
props: React.ComponentProps<RouteComponent>,
): ReactElement =>
React.createElement(LoadedComponent || LazyComponent, props)
Component.preload = loadComponent
+1 -1
View File
@@ -8,7 +8,7 @@ describe('Test useRoute fn', () => {
test('match routes by ids', () => {
vi.mock('./useInternalRouter.tsx', () => ({
useInternalRouter: (): { routesById: Record<string, any> } => {
useInternalRouter: (): { routesById: Record<string, { id: string }> } => {
return {
routesById: {
'/': { id: '/' },
+1 -1
View File
@@ -16,7 +16,7 @@ interface UseRouterHook {
/**
* This object contains all the query params of the current route
*/
query: Record<string, any>
query: Record<string, unknown>
/**
* Returns the current pathname
+3 -1
View File
@@ -67,5 +67,7 @@ export const useRouterStore = create<RouterState>()((set) => ({
pendingMatches: [],
cachedMatches: [],
statusCode: 200,
updateLocation: (location: ParsedLocation): void => set({ location }),
updateLocation: (location: ParsedLocation): void => {
set({ location })
},
}))
@@ -13,7 +13,7 @@ interface UseServerSidePropsReturn<TData> {
}
interface TuonoApi {
data?: any
data?: unknown
info: {
redirect_destination?: string
}
+1 -1
View File
@@ -77,7 +77,7 @@ export class Route {
this.fullPath = fullPath || ''
}
addChildren(routes: Array<Route>): Route {
addChildren(routes: Array<Route>): this {
this.children = routes
return this
}
-2
View File
@@ -17,8 +17,6 @@ interface RouterOptions {
routeTree?: RouteTree
}
export type RouterType = any
export function createRouter(options: CreateRouterOptions): Router {
return new Router(options)
}
+1 -1
View File
@@ -84,7 +84,7 @@ export function serverSideRendering(routeTree: RouteTree) {
${renderToStaticMarkup(
<script
dangerouslySetInnerHTML={{
__html: `window.__TUONO_SSR_PROPS__=${payload}`,
__html: `window.__TUONO_SSR_PROPS__=${payload as string}`,
}}
/>,
)}
@@ -38,7 +38,9 @@ export class MessagePortPolyfill implements MessagePort {
if (this.onmessage) {
this.onmessage(event)
}
this.onmessageListeners.forEach((listener) => listener(event))
this.onmessageListeners.forEach((listener) => {
listener(event)
})
return true
}