Skip to content

Commit bf97ebc

Browse files
authored
Turn on type-aware lint rules (#2259)
* turn on a couple of type-aware lint rules * turn on recommended-type-checked except for all the ones I hate * hm we actually sort of caught a bug and I'm not sure why eslint made this possible
1 parent a18c7a8 commit bf97ebc

File tree

18 files changed

+53
-31
lines changed

18 files changed

+53
-31
lines changed

.eslintrc.cjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ module.exports = {
66
parser: '@typescript-eslint/parser',
77
parserOptions: {
88
warnOnUnsupportedTypeScriptVersion: false,
9+
// this config is needed for type aware lint rules
10+
project: true,
11+
tsconfigRootDir: __dirname,
912
},
1013
extends: [
1114
'eslint:recommended',
15+
'plugin:@typescript-eslint/recommended-type-checked',
1216
'plugin:@typescript-eslint/strict',
1317
'plugin:@typescript-eslint/stylistic',
1418
'plugin:jsx-a11y/recommended',
@@ -45,6 +49,18 @@ module.exports = {
4549
'error',
4650
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
4751
],
52+
53+
// disabling the type-aware rules we don't like
54+
// https://typescript-eslint.io/getting-started/typed-linting/
55+
'@typescript-eslint/no-floating-promises': 'off',
56+
'@typescript-eslint/no-misused-promises': 'off',
57+
'@typescript-eslint/unbound-method': 'off',
58+
'@typescript-eslint/no-unsafe-argument': 'off',
59+
'@typescript-eslint/no-unsafe-assignment': 'off',
60+
'@typescript-eslint/no-unsafe-call': 'off',
61+
'@typescript-eslint/no-unsafe-member-access': 'off',
62+
'@typescript-eslint/no-unsafe-return': 'off',
63+
4864
eqeqeq: ['error', 'always', { null: 'ignore' }],
4965
'import/no-default-export': 'error',
5066
'import/no-unresolved': 'off', // plugin doesn't know anything

app/components/form/SideModalForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88
import { useEffect, useId, type ReactNode } from 'react'
99
import type { FieldValues, UseFormReturn } from 'react-hook-form'
10-
import { useNavigationType } from 'react-router-dom'
10+
import { NavigationType, useNavigationType } from 'react-router-dom'
1111

1212
import type { ApiError } from '@oxide/api'
1313

@@ -57,7 +57,7 @@ type SideModalFormProps<TFieldValues extends FieldValues> = {
5757
* any way to distinguish between fresh pageload and back/forward.
5858
*/
5959
export function useShouldAnimateModal() {
60-
return useNavigationType() === 'PUSH'
60+
return useNavigationType() === NavigationType.Push
6161
}
6262

6363
export function SideModalForm<TFieldValues extends FieldValues>({

app/components/form/fields/DateTimeRangePicker.spec.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe.skip('custom mode', () => {
9797
expect(screen.getByRole('button', { name: 'Load' })).toHaveClass('visually-disabled')
9898
})
9999

100-
it('clicking load after changing date changes range', async () => {
100+
it('clicking load after changing date changes range', () => {
101101
const { setRange } = renderLastDay()
102102

103103
// expect(screen.getByLabelText('Start time')).toHaveValue(dateForInput(subDays(now, 1)))
@@ -125,7 +125,7 @@ describe.skip('custom mode', () => {
125125
})
126126
})
127127

128-
it('clicking reset after changing inputs resets inputs', async () => {
128+
it('clicking reset after changing inputs resets inputs', () => {
129129
const { setRange } = renderLastDay()
130130

131131
// expect(screen.getByLabelText('Start time')).toHaveValue(dateForInput(subDays(now, 1)))

app/components/form/fields/ListboxField.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type ListboxFieldProps<
2727
className?: string
2828
label?: string
2929
required?: boolean
30-
description?: string | React.ReactNode | React.ReactNode
30+
description?: string | React.ReactNode
3131
tooltipText?: string
3232
control: Control<TFieldValues>
3333
disabled?: boolean

app/forms/image-upload.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ export function CreateImageSideModalForm() {
273273
// coordinating when to cleanup, we make cleanup idempotent by having it check
274274
// whether it has already been run, or more concretely before each action,
275275
// check whether it needs to be done
276-
async function closeModal() {
276+
function closeModal() {
277277
if (allDone) {
278278
backToImages()
279279
return

app/forms/vpc-edit.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function EditVpcSideModalForm() {
4040
const onDismiss = () => navigate(pb.vpcs({ project }))
4141

4242
const editVpc = useApiMutation('vpcUpdate', {
43-
async onSuccess(vpc) {
43+
onSuccess(vpc) {
4444
queryClient.invalidateQueries('vpcList')
4545
queryClient.setQueryData(
4646
'vpcView',

app/pages/SiloAccessPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export function SiloAccessPage() {
139139
doDelete: () =>
140140
updatePolicy.mutateAsync({
141141
// we know policy is there, otherwise there's no row to display
142-
body: deleteRole(row.id, siloPolicy!),
142+
body: deleteRole(row.id, siloPolicy),
143143
}),
144144
label: (
145145
<span>

app/pages/project/access/ProjectAccessPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export function ProjectAccessPage() {
169169
updatePolicy.mutateAsync({
170170
path: { project },
171171
// we know policy is there, otherwise there's no row to display
172-
body: deleteRole(row.id, projectPolicy!),
172+
body: deleteRole(row.id, projectPolicy),
173173
}),
174174
// TODO: explain that this will not affect the role inherited from
175175
// the silo or roles inherited from group membership. Ideally we'd

app/pages/project/instances/actions.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,10 @@ export const useMakeInstanceActions = (
7070
onActivate() {
7171
confirmAction({
7272
actionType: 'danger',
73-
doAction: async () =>
74-
stopInstance.mutate(instanceParams, {
73+
doAction: () =>
74+
stopInstance.mutateAsync(instanceParams, {
7575
onSuccess: () =>
7676
addToast({ title: `Stopping instance '${instance.name}'` }),
77-
onError: (error) =>
78-
addToast({
79-
variant: 'error',
80-
title: `Error stopping instance '${instance.name}'`,
81-
content: error.message,
82-
}),
8377
}),
8478
modalTitle: 'Confirm stop instance',
8579
modalContent: (
@@ -89,7 +83,7 @@ export const useMakeInstanceActions = (
8983
freed.
9084
</p>
9185
),
92-
errorTitle: `Could not stop ${instance.name}`,
86+
errorTitle: `Error stopping ${instance.name}`,
9387
})
9488
},
9589
disabled: !instanceCan.stop(instance) && (

app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ const staticColumns = [
7272
cell: (info) => {
7373
const { hosts, ports, protocols } = info.getValue()
7474
const children = [
75-
...(hosts || []).map((tv, i) => <TypeValueCell key={`${tv}-${i}`} {...tv} />),
75+
...(hosts || []).map((tv, i) => (
76+
<TypeValueCell key={`host-${tv.type}-${tv.value}-${i}`} {...tv} />
77+
)),
7678
...(protocols || []).map((p, i) => <Badge key={`${p}-${i}`}>{p}</Badge>),
7779
...(ports || []).map((p, i) => (
7880
<TypeValueCell key={`port-${p}-${i}`} type="Port" value={p} />

0 commit comments

Comments
 (0)