Enable type-aware linting and replace biome-ignore with oxlint-disable

- Enable typeAware option and no-explicit-any (error) in vite.config.ts
- Ignore generated binding files from linting
- Convert all 96 biome-ignore comments to oxlint-disable equivalents
- Add suppression comments for 3 previously uncovered any usages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-03-13 08:24:34 -07:00
parent 7670ab007f
commit 44a331929f
73 changed files with 106 additions and 97 deletions

View File

@@ -22,7 +22,7 @@ export function DetailsBanner({
storageKey,
...extraProps
}: Props) {
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to recompute the atom when storageKey changes
// oxlint-disable-next-line react-hooks/exhaustive-deps -- We only want to recompute the atom when storageKey changes
const openAtom = useMemo(
() =>
storageKey

View File

@@ -753,7 +753,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
if (item.type === 'separator') {
return (
<Separator
// biome-ignore lint/suspicious/noArrayIndexKey: Nothing else available
// oxlint-disable-next-line react/no-array-index-key -- Nothing else available
key={i}
className={classNames('my-1.5', item.label ? 'ml-2' : null)}
>
@@ -763,8 +763,8 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
}
if (item.type === 'content') {
return (
// biome-ignore lint/a11y/noStaticElementInteractions: Needs to be clickable but want to support nested buttons
// biome-ignore lint/suspicious/noArrayIndexKey: index is fine
// oxlint-disable-next-line jsx-a11y/no-static-element-interactions
// oxlint-disable-next-line react/no-array-index-key
<div key={i} className={classNames('my-1 mx-2 max-w-xs')} onClick={onClose}>
{item.label}
</div>
@@ -778,7 +778,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
onFocus={handleFocus}
onSelect={handleSelect}
onHover={handleItemHover}
// biome-ignore lint/suspicious/noArrayIndexKey: It's fine
// oxlint-disable-next-line react/no-array-index-key
key={i}
item={item}
/>
@@ -786,7 +786,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
})}
</VStack>
{activeSubmenu && (
// biome-ignore lint/a11y/noStaticElementInteractions: Container div that cancels hover timeout
// oxlint-disable-next-line jsx-a11y/no-static-element-interactions -- Container div that cancels hover timeout
<div
ref={submenuRef}
onMouseEnter={() => {

View File

@@ -327,7 +327,7 @@ function EditorInner({
);
// Update the language extension when the language changes
// biome-ignore lint/correctness/useExhaustiveDependencies: intentionally limited deps
// oxlint-disable-next-line react-hooks/exhaustive-deps -- intentionally limited deps
useEffect(() => {
if (cm.current === null) return;
const { view, languageCompartment } = cm.current;
@@ -361,7 +361,7 @@ function EditorInner({
]);
// Initialize the editor when ref mounts
// biome-ignore lint/correctness/useExhaustiveDependencies: only reinitialize when necessary
// oxlint-disable-next-line react-hooks/exhaustive-deps -- only reinitialize when necessary
const initEditorRef = useCallback(
function initEditorRef(container: HTMLDivElement | null) {
if (container === null) {

View File

@@ -1,4 +1,4 @@
// biome-ignore-all lint: Disable for generated file
/* oxlint-disable */
// This file was generated by lezer-generator. You probably shouldn't edit it.
import { LRParser } from '@lezer/lr';
import { highlight } from './highlight';

View File

@@ -14,7 +14,7 @@ const tooltip = hoverTooltip(
let match: RegExpExecArray | null;
let found: { start: number; end: number } | null = null;
// biome-ignore lint/suspicious/noAssignInExpressions: none
// oxlint-disable-next-line no-cond-assign
while ((match = REGEX.exec(text))) {
const start = from + match.index;
const end = start + match[0].length;

View File

@@ -20,7 +20,7 @@ export function jsonParseLinter(options?: JsonLintOptions) {
mode: (options?.allowComments ?? true) ? 'cjson' : 'json',
ignoreTrailingCommas: options?.allowTrailingCommas ?? false,
});
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
} catch (err: any) {
if (!('location' in err)) {
return [];

View File

@@ -1,4 +1,4 @@
// biome-ignore-all lint/suspicious/noTemplateCurlyInString: We're testing this, specifically
/* oxlint-disable no-template-curly-in-string */
import { describe, expect, test } from 'vite-plus/test';
import { parser } from './twig';

View File

@@ -35,7 +35,7 @@ export function HotkeyRaw({ labelParts, className, variant }: HotkeyRawProps) {
)}
>
{labelParts.map((char, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: none
// oxlint-disable-next-line react/no-array-index-key
<div key={index} className="min-w-[1em] text-center">
{char}
</div>

View File

@@ -144,7 +144,7 @@ function BaseInput({
isFocused: () => editorRef.current?.hasFocus ?? false,
value: () => editorRef.current?.state.doc.toString() ?? '',
dispatch: (...args) => {
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
editorRef.current?.dispatch(...(args as any));
},
selectAll() {

View File

@@ -5,7 +5,7 @@ import { Icon } from './Icon';
interface Props {
depth?: number;
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
attrValue: any;
attrKey?: string | number;
attrKeyJsonPath?: string;
@@ -54,10 +54,10 @@ export const JsonAttributeTree = ({
if (jsonType === '[object Array]') {
return {
children: isExpanded
? // biome-ignore lint/suspicious/noExplicitAny: none
? // oxlint-disable-next-line no-explicit-any
attrValue.flatMap((v: any, i: number) => (
<JsonAttributeTree
// biome-ignore lint/suspicious/noArrayIndexKey: none
// oxlint-disable-next-line react/no-array-index-key
key={i}
depth={depth + 1}
attrValue={v}

View File

@@ -13,7 +13,7 @@ export function KeyValueRows({ children }: Props) {
<table className="text-editor font-mono min-w-0 w-full mb-auto">
<tbody className="divide-y divide-surface-highlight">
{childArray.map((child, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: none
// oxlint-disable-next-line react/no-array-index-key
<tr key={i}>{child}</tr>
))}
</tbody>

View File

@@ -37,7 +37,7 @@ export function Label({
{required === true && <span className="text-text-subtlest">*</span>}
</span>
{tags.map((tag, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: none
// oxlint-disable-next-line react/no-array-index-key
<span key={i} className="text-xs text-text-subtlest">
({tag})
</span>

View File

@@ -145,7 +145,7 @@ export function PairEditor({
[handle, pairs, setRef],
);
// biome-ignore lint/correctness/useExhaustiveDependencies: Only care about forceUpdateKey
// oxlint-disable-next-line react-hooks/exhaustive-deps -- Only care about forceUpdateKey
useEffect(() => {
// Remove empty headers on initial render and ensure they all have valid ids (pairs didn't use to have IDs)
const newPairs: PairWithId[] = [];

View File

@@ -195,7 +195,7 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
key={forceUpdateKey}
type={type === 'password' && !obscured ? 'text' : type}
name={name}
// biome-ignore lint/a11y/noAutofocus: Who cares
// oxlint-disable-next-line jsx-a11y/no-autofocus
autoFocus={autoFocus}
defaultValue={defaultValue ?? undefined}
autoComplete="off"

View File

@@ -20,7 +20,7 @@ interface HStackProps extends BaseStackProps {
export const HStack = forwardRef(function HStack(
{ className, space, children, alignItems = 'center', ...props }: HStackProps,
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
ref: ForwardedRef<any>,
) {
return (
@@ -41,7 +41,7 @@ export type VStackProps = BaseStackProps & {
export const VStack = forwardRef(function VStack(
{ className, space, children, ...props }: VStackProps,
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
ref: ForwardedRef<any>,
) {
return (
@@ -65,7 +65,7 @@ type BaseStackProps = HTMLAttributes<HTMLElement> & {
const BaseStack = forwardRef(function BaseStack(
{ className, alignItems, justifyContent, wrap, children, as, ...props }: BaseStackProps,
// biome-ignore lint/suspicious/noExplicitAny: none
// oxlint-disable-next-line no-explicit-any
ref: ForwardedRef<any>,
) {
const Component = as ?? 'div';

View File

@@ -110,7 +110,7 @@ export function Tooltip({ children, className, content, tabIndex, size = 'md' }:
/>
</div>
</Portal>
{/** biome-ignore lint/a11y/useSemanticElements: Needs to be usable in other buttons */}
{/* oxlint-disable-next-line jsx-a11y/prefer-tag-over-role -- Needs to be usable in other buttons */}
<span
ref={triggerRef}
role="button"

View File

@@ -111,7 +111,7 @@ function TreeInner<T extends { id: string }>(
}, []);
// Select the first item on first render
// biome-ignore lint/correctness/useExhaustiveDependencies: Only used for initial render
// oxlint-disable-next-line react-hooks/exhaustive-deps -- Only used for initial render
useEffect(() => {
const ids = jotaiStore.get(selectedIdsFamily(treeId));
const fallback = selectableItems[0];
@@ -736,7 +736,7 @@ function DropRegionAfterList({
onContextMenu?: (e: MouseEvent<HTMLDivElement>) => void;
}) {
const { setNodeRef } = useDroppable({ id });
// biome-ignore lint/a11y/noStaticElementInteractions: Meh
// oxlint-disable-next-line jsx-a11y/no-static-element-interactions
return <div ref={setNodeRef} onContextMenu={onContextMenu} />;
}

View File

@@ -19,7 +19,7 @@ export const TreeIndentGuide = memo(function TreeIndentGuide({
<div className="flex">
{Array.from({ length: depth }).map((_, i) => (
<div
// biome-ignore lint/suspicious/noArrayIndexKey: none
// oxlint-disable-next-line react/no-array-index-key
key={i}
className={classNames(
'w-[calc(1rem+0.5px)] border-r border-r-text-subtlest',

View File

@@ -41,7 +41,7 @@ export function equalSubtree<T extends { id: string }>(
}
for (let i = 0; i < ak.length; i++) {
// biome-ignore lint/style/noNonNullAssertion: none
// oxlint-disable-next-line no-non-null-assertion
if (!equalSubtree(ak[i]!, bk[i]!, getItemKey)) return false;
}