feat: No Explicit Any (#8601)

## Summary
- Add `typescript/no-explicit-any` rule to `.oxlintrc.json` to enforce
no explicit `any` types
- Fix all 40 instances of explicit `any` throughout the codebase
- Improve type safety with proper TypeScript types

## Changes Made

### Configuration
- Added `typescript/no-explicit-any` rule to `.oxlintrc.json`

### Type Fixes
- Replaced `any` with `unknown` for truly unknown types
- Updated generic type parameters to use `unknown` defaults instead of
`any`
- Fixed method `this` parameters to avoid variance issues
- Updated component props to match new generic types
- Fixed test mocks to use proper type assertions

### Key Files Modified
- `src/types/treeExplorerTypes.ts`: Updated TreeExplorerNode interface
generics
- `src/platform/settings/types.ts`: Fixed SettingParams generic default
- `src/lib/litegraph/src/LGraph.ts`: Fixed ParamsArray type constraint
- `src/extensions/core/electronAdapter.ts`: Fixed onChange callbacks
- `src/views/GraphView.vue`: Added proper type imports
- Multiple test files: Fixed type assertions and mocks

## Test Plan
- [x] All lint checks pass (`pnpm lint`)
- [x] TypeScript compilation succeeds (`pnpm typecheck`)
- [x] Pre-commit hooks pass
- [x] No regression in functionality

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8601-feat-add-typescript-no-explicit-any-rule-and-fix-all-instances-2fd6d73d365081fd9beef75d5a6daf5b)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
This commit is contained in:
Johnpaul Chiwetelu
2026-02-12 00:13:48 +01:00
committed by GitHub
parent 92b7437d86
commit 4fc1d2ef5b
28 changed files with 242 additions and 151 deletions

View File

@@ -72,7 +72,7 @@ import FormItem from '@/components/common/FormItem.vue'
import PanelTemplate from '@/components/dialog/content/setting/PanelTemplate.vue'
import Button from '@/components/ui/button/Button.vue'
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
import type { ServerConfig } from '@/constants/serverConfig'
import type { ServerConfig, ServerConfigValue } from '@/constants/serverConfig'
import { useSettingStore } from '@/platform/settings/settingStore'
import type { FormItem as FormItemType } from '@/platform/settings/types'
import { useToastStore } from '@/platform/updates/common/toastStore'
@@ -133,7 +133,7 @@ onBeforeUnmount(() => {
})
})
const translateItem = (item: ServerConfig<any>): FormItemType => {
const translateItem = (item: ServerConfig<ServerConfigValue>): FormItemType => {
return {
...item,
name: t(`serverConfigItems.${item.id}.name`, item.name),

View File

@@ -165,7 +165,9 @@ export const CORE_SETTINGS: SettingParams[] = [
defaultsByInstallVersion: {
'1.25.0': 'legacy'
},
onChange: async (newValue: string, oldValue?: string) => {
onChange: async (val: unknown, old?: unknown) => {
const newValue = val as string
const oldValue = old as string | undefined
if (!oldValue) return
const settingStore = useSettingStore()
@@ -194,7 +196,8 @@ export const CORE_SETTINGS: SettingParams[] = [
{ value: 'select', text: 'Select' }
],
versionAdded: '1.27.4',
onChange: async (newValue: string) => {
onChange: async (val: unknown) => {
const newValue = val as string
const settingStore = useSettingStore()
const navigationMode = settingStore.get('Comfy.Canvas.NavigationMode')
@@ -223,7 +226,8 @@ export const CORE_SETTINGS: SettingParams[] = [
{ value: 'zoom', text: 'Zoom in/out' }
],
versionAdded: '1.27.4',
onChange: async (newValue: string) => {
onChange: async (val: unknown) => {
const newValue = val as string
const settingStore = useSettingStore()
const navigationMode = settingStore.get('Comfy.Canvas.NavigationMode')
@@ -569,7 +573,8 @@ export const CORE_SETTINGS: SettingParams[] = [
type: 'combo',
options: ['Disabled', 'Top'],
tooltip: 'Enable the redesigned top menu bar.',
migrateDeprecatedValue: (value: string) => {
migrateDeprecatedValue: (val: unknown) => {
const value = val as string
// Floating is now supported by dragging the docked actionbar off.
if (value === 'Floating') {
return 'Top'
@@ -585,7 +590,8 @@ export const CORE_SETTINGS: SettingParams[] = [
type: 'combo',
options: ['Sidebar', 'Topbar'],
defaultValue: 'Topbar',
migrateDeprecatedValue: (value: string) => {
migrateDeprecatedValue: (val: unknown) => {
const value = val as string
if (value === 'Topbar (2nd-row)') {
return 'Topbar'
}
@@ -615,9 +621,8 @@ export const CORE_SETTINGS: SettingParams[] = [
defaultValue: [] as Keybinding[],
versionAdded: '1.3.7',
versionModified: '1.7.3',
migrateDeprecatedValue: (
value: (Keybinding & { targetSelector?: string })[]
) => {
migrateDeprecatedValue: (val: unknown) => {
const value = val as (Keybinding & { targetSelector?: string })[]
return value.map((keybinding) => {
if (keybinding.targetSelector === '#graph-canvas') {
keybinding.targetElementId = 'graph-canvas-container'
@@ -886,7 +891,8 @@ export const CORE_SETTINGS: SettingParams[] = [
type: 'hidden',
defaultValue: 'dark',
versionModified: '1.6.7',
migrateDeprecatedValue(value: string) {
migrateDeprecatedValue(val: unknown) {
const value = val as string
// Legacy custom palettes were prefixed with 'custom_'
return value.startsWith('custom_') ? value.replace('custom_', '') : value
}

View File

@@ -118,7 +118,7 @@ describe('useSettingStore', () => {
name: 'test.setting',
type: 'text',
defaultValue: 'default',
migrateDeprecatedValue: (value: string) => value.toUpperCase()
migrateDeprecatedValue: (val: unknown) => (val as string).toUpperCase()
}
store.settingValues['test.setting'] = 'oldvalue'

View File

@@ -26,11 +26,11 @@ export interface SettingOption {
value?: string | number
}
export interface SettingParams<TValue = any> extends FormItem {
export interface SettingParams<TValue = unknown> extends FormItem {
id: keyof Settings
defaultValue: TValue | (() => TValue)
defaultsByInstallVersion?: Record<`${number}.${number}.${number}`, TValue>
onChange?: (newValue: TValue, oldValue?: TValue) => void
onChange?(newValue: TValue, oldValue?: TValue): void
// By default category is id.split('.'). However, changing id to assign
// new category has poor backward compatibility. Use this field to overwrite
// default category from id.