fix: replace as-unknown-as casts with safer patterns (#9107)

## Summary

- Replace 83 `as unknown as` double casts with safer alternatives across
33 files
- Use `as Partial<X> as X` pattern where TypeScript allows it
- Create/reuse factory functions from `litegraphTestUtils.ts` for mock
objects
- Widen `getWorkflowDataFromFile` return type to include `ComfyMetadata`
directly
- Reduce total `as unknown as` count from ~153 to 71

The remaining 71 occurrences are genuinely necessary due to cross-schema
casts, generic variance, missing index signatures, Float64Array-to-tuple
conversions, and DOM type incompatibilities.

## Test plan

- [x] `pnpm typecheck` passes
- [x] `pnpm lint` passes
- [x] All affected unit tests pass

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9107-fix-replace-as-unknown-as-casts-with-safer-patterns-3106d73d3650815cb5bcd613ad635bd7)
by [Unito](https://www.unito.io)
This commit is contained in:
Johnpaul Chiwetelu
2026-02-23 05:46:12 +01:00
committed by GitHub
parent 8998d92e1b
commit 02e926471f
33 changed files with 282 additions and 346 deletions

View File

@@ -104,7 +104,7 @@ describe('useCanvasInteractions', () => {
it('should return early when canvas is null', () => {
const { getCanvas } = useCanvasStore()
vi.mocked(getCanvas).mockReturnValue(null as unknown as LGraphCanvas) // TODO: Fix misaligned types
vi.mocked(getCanvas).mockReturnValue(null!)
const { handlePointer } = useCanvasInteractions()
const mockEvent = createMockPointerEvent(1)

View File

@@ -2,8 +2,8 @@ import { mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { computed, nextTick } from 'vue'
import type { LGraphCanvas } from '@/lib/litegraph/src/LGraphCanvas'
import { useTransformState } from '@/renderer/core/layout/transform/useTransformState'
import { createMockCanvas } from '@/utils/__tests__/litegraphTestUtils'
import TransformPane from '../transform/TransformPane.vue'
@@ -29,8 +29,8 @@ vi.mock('@/renderer/core/layout/transform/useTransformState', () => {
}
})
function createMockCanvas(): LGraphCanvas {
return {
function createMockLGraphCanvas() {
return createMockCanvas({
canvas: {
addEventListener: vi.fn(),
removeEventListener: vi.fn()
@@ -39,7 +39,7 @@ function createMockCanvas(): LGraphCanvas {
offset: [0, 0],
scale: 1
}
} as unknown as LGraphCanvas
})
}
describe('TransformPane', () => {
@@ -52,7 +52,7 @@ describe('TransformPane', () => {
describe('component mounting', () => {
it('should mount successfully with minimal props', () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -69,7 +69,7 @@ describe('TransformPane', () => {
transformOrigin: '0 0'
}
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -83,7 +83,7 @@ describe('TransformPane', () => {
})
it('should render slot content', () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -100,7 +100,7 @@ describe('TransformPane', () => {
describe('RAF synchronization', () => {
it('should call syncWithCanvas during RAF updates', async () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -119,7 +119,7 @@ describe('TransformPane', () => {
describe('canvas event listeners', () => {
it('should add event listeners to canvas on mount', async () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -151,7 +151,7 @@ describe('TransformPane', () => {
})
it('should remove event listeners on unmount', async () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -186,7 +186,7 @@ describe('TransformPane', () => {
describe('interaction state management', () => {
it('should apply interacting class during interactions', async () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -204,7 +204,7 @@ describe('TransformPane', () => {
})
it('should handle pointer events for node delegation', async () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
const wrapper = mount(TransformPane, {
props: {
canvas: mockCanvas
@@ -225,7 +225,7 @@ describe('TransformPane', () => {
describe('transform state integration', () => {
it('should provide transform utilities to child components', () => {
const mockCanvas = createMockCanvas()
const mockCanvas = createMockLGraphCanvas()
mount(TransformPane, {
props: {
canvas: mockCanvas

View File

@@ -4,11 +4,7 @@ import { computed, shallowRef } from 'vue'
import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import type { GraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
import type {
LGraph,
LGraphCanvas,
LGraphNode
} from '@/lib/litegraph/src/litegraph'
import type { LGraphCanvas, LGraphNode } from '@/lib/litegraph/src/litegraph'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
@@ -64,7 +60,7 @@ vi.mock('@/composables/graph/useGraphNodeManager', () => {
})
vi.mock('@/composables/graph/useVueNodeLifecycle', () => {
const nodeManager = useGraphNodeManager(undefined as unknown as LGraph)
const nodeManager = useGraphNodeManager(null!)
return {
useVueNodeLifecycle: vi.fn(() => ({
nodeManager

View File

@@ -108,7 +108,7 @@ function createPointerEvent(
preventDefault: vi.fn(),
stopPropagation: vi.fn(),
...overrides
} as unknown as PointerEvent
} as Partial<PointerEvent> as PointerEvent
}
function startResizeAt(