mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-10 23:50:00 +00:00
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:
committed by
GitHub
parent
8998d92e1b
commit
02e926471f
@@ -72,7 +72,9 @@ describe('useNodePreviewAndDrag', () => {
|
||||
toJSON: () => ({})
|
||||
})
|
||||
|
||||
const mockEvent = { currentTarget: mockElement } as unknown as MouseEvent
|
||||
const mockEvent = {
|
||||
currentTarget: mockElement
|
||||
} as Partial<MouseEvent> as MouseEvent
|
||||
result.handleMouseEnter(mockEvent)
|
||||
|
||||
expect(result.isHovered.value).toBe(true)
|
||||
@@ -83,7 +85,9 @@ describe('useNodePreviewAndDrag', () => {
|
||||
const result = useNodePreviewAndDrag(nodeDef)
|
||||
|
||||
const mockElement = document.createElement('div')
|
||||
const mockEvent = { currentTarget: mockElement } as unknown as MouseEvent
|
||||
const mockEvent = {
|
||||
currentTarget: mockElement
|
||||
} as Partial<MouseEvent> as MouseEvent
|
||||
result.handleMouseEnter(mockEvent)
|
||||
|
||||
expect(result.isHovered.value).toBe(false)
|
||||
@@ -150,7 +154,7 @@ describe('useNodePreviewAndDrag', () => {
|
||||
const mockEvent = {
|
||||
clientX: 100,
|
||||
clientY: 200
|
||||
} as unknown as DragEvent
|
||||
} as Partial<DragEvent> as DragEvent
|
||||
|
||||
result.handleDragEnd(mockEvent)
|
||||
|
||||
@@ -168,7 +172,7 @@ describe('useNodePreviewAndDrag', () => {
|
||||
dataTransfer: { dropEffect: 'none' },
|
||||
clientX: 300,
|
||||
clientY: 400
|
||||
} as unknown as DragEvent
|
||||
} as Partial<DragEvent> as DragEvent
|
||||
|
||||
result.handleDragEnd(mockEvent)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick, reactive } from 'vue'
|
||||
|
||||
import { useQueueNotificationBanners } from '@/composables/queue/useQueueNotificationBanners'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useQueueStore } from '@/stores/queueStore'
|
||||
|
||||
@@ -135,7 +134,7 @@ describe(useQueueNotificationBanners, () => {
|
||||
const { wrapper, composable } = mountComposable()
|
||||
|
||||
try {
|
||||
;(api as unknown as EventTarget).dispatchEvent(
|
||||
mockApi.dispatchEvent(
|
||||
new CustomEvent('promptQueued', { detail: { batchCount: 4 } })
|
||||
)
|
||||
await nextTick()
|
||||
@@ -157,7 +156,7 @@ describe(useQueueNotificationBanners, () => {
|
||||
const { wrapper, composable } = mountComposable()
|
||||
|
||||
try {
|
||||
;(api as unknown as EventTarget).dispatchEvent(
|
||||
mockApi.dispatchEvent(
|
||||
new CustomEvent('promptQueueing', {
|
||||
detail: { requestId: 1, batchCount: 2 }
|
||||
})
|
||||
@@ -170,7 +169,7 @@ describe(useQueueNotificationBanners, () => {
|
||||
requestId: 1
|
||||
})
|
||||
|
||||
;(api as unknown as EventTarget).dispatchEvent(
|
||||
mockApi.dispatchEvent(
|
||||
new CustomEvent('promptQueued', {
|
||||
detail: { requestId: 1, batchCount: 2 }
|
||||
})
|
||||
@@ -191,7 +190,7 @@ describe(useQueueNotificationBanners, () => {
|
||||
const { wrapper, composable } = mountComposable()
|
||||
|
||||
try {
|
||||
;(api as unknown as EventTarget).dispatchEvent(
|
||||
mockApi.dispatchEvent(
|
||||
new CustomEvent('promptQueued', { detail: { batchCount: 0 } })
|
||||
)
|
||||
await nextTick()
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { app } from '@/scripts/app'
|
||||
import { createMockLGraphNode } from '@/utils/__tests__/litegraphTestUtils'
|
||||
import { createNode, isImageNode } from '@/utils/litegraphUtil'
|
||||
import {
|
||||
cloneDataTransfer,
|
||||
@@ -15,12 +16,12 @@ import {
|
||||
usePaste
|
||||
} from './usePaste'
|
||||
|
||||
function createMockNode() {
|
||||
return {
|
||||
function createMockNode(): LGraphNode {
|
||||
return createMockLGraphNode({
|
||||
pos: [0, 0],
|
||||
pasteFile: vi.fn(),
|
||||
pasteFiles: vi.fn()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function createImageFile(
|
||||
@@ -84,7 +85,8 @@ vi.mock('@/scripts/app', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/litegraph/src/litegraph', () => ({
|
||||
vi.mock('@/lib/litegraph/src/litegraph', async (importOriginal) => ({
|
||||
...(await importOriginal()),
|
||||
LiteGraph: {
|
||||
createNode: vi.fn()
|
||||
}
|
||||
@@ -111,15 +113,12 @@ describe('pasteImageNode', () => {
|
||||
|
||||
it('should create new LoadImage node when no image node provided', async () => {
|
||||
const mockNode = createMockNode()
|
||||
vi.mocked(createNode).mockResolvedValue(mockNode as unknown as LGraphNode)
|
||||
vi.mocked(createNode).mockResolvedValue(mockNode)
|
||||
|
||||
const file = createImageFile()
|
||||
const dataTransfer = createDataTransfer([file])
|
||||
|
||||
await pasteImageNode(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
dataTransfer.items
|
||||
)
|
||||
await pasteImageNode(mockCanvas, dataTransfer.items)
|
||||
|
||||
expect(createNode).toHaveBeenCalledWith(mockCanvas, 'LoadImage')
|
||||
expect(mockNode.pasteFile).toHaveBeenCalledWith(file)
|
||||
@@ -130,11 +129,7 @@ describe('pasteImageNode', () => {
|
||||
const file = createImageFile()
|
||||
const dataTransfer = createDataTransfer([file])
|
||||
|
||||
await pasteImageNode(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
dataTransfer.items,
|
||||
mockNode as unknown as LGraphNode
|
||||
)
|
||||
await pasteImageNode(mockCanvas, dataTransfer.items, mockNode)
|
||||
|
||||
expect(mockNode.pasteFile).toHaveBeenCalledWith(file)
|
||||
expect(mockNode.pasteFiles).toHaveBeenCalledWith([file])
|
||||
@@ -146,11 +141,7 @@ describe('pasteImageNode', () => {
|
||||
const file2 = createImageFile('test2.jpg', 'image/jpeg')
|
||||
const dataTransfer = createDataTransfer([file1, file2])
|
||||
|
||||
await pasteImageNode(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
dataTransfer.items,
|
||||
mockNode as unknown as LGraphNode
|
||||
)
|
||||
await pasteImageNode(mockCanvas, dataTransfer.items, mockNode)
|
||||
|
||||
expect(mockNode.pasteFile).toHaveBeenCalledWith(file1)
|
||||
expect(mockNode.pasteFiles).toHaveBeenCalledWith([file1, file2])
|
||||
@@ -160,11 +151,7 @@ describe('pasteImageNode', () => {
|
||||
const mockNode = createMockNode()
|
||||
const dataTransfer = createDataTransfer()
|
||||
|
||||
await pasteImageNode(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
dataTransfer.items,
|
||||
mockNode as unknown as LGraphNode
|
||||
)
|
||||
await pasteImageNode(mockCanvas, dataTransfer.items, mockNode)
|
||||
|
||||
expect(mockNode.pasteFile).not.toHaveBeenCalled()
|
||||
expect(mockNode.pasteFiles).not.toHaveBeenCalled()
|
||||
@@ -176,11 +163,7 @@ describe('pasteImageNode', () => {
|
||||
const textFile = new File([''], 'test.txt', { type: 'text/plain' })
|
||||
const dataTransfer = createDataTransfer([textFile, imageFile])
|
||||
|
||||
await pasteImageNode(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
dataTransfer.items,
|
||||
mockNode as unknown as LGraphNode
|
||||
)
|
||||
await pasteImageNode(mockCanvas, dataTransfer.items, mockNode)
|
||||
|
||||
expect(mockNode.pasteFile).toHaveBeenCalledWith(imageFile)
|
||||
expect(mockNode.pasteFiles).toHaveBeenCalledWith([imageFile])
|
||||
@@ -196,16 +179,13 @@ describe('pasteImageNodes', () => {
|
||||
const mockNode1 = createMockNode()
|
||||
const mockNode2 = createMockNode()
|
||||
vi.mocked(createNode)
|
||||
.mockResolvedValueOnce(mockNode1 as unknown as LGraphNode)
|
||||
.mockResolvedValueOnce(mockNode2 as unknown as LGraphNode)
|
||||
.mockResolvedValueOnce(mockNode1)
|
||||
.mockResolvedValueOnce(mockNode2)
|
||||
|
||||
const file1 = createImageFile('test1.png')
|
||||
const file2 = createImageFile('test2.jpg', 'image/jpeg')
|
||||
|
||||
const result = await pasteImageNodes(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
[file1, file2]
|
||||
)
|
||||
const result = await pasteImageNodes(mockCanvas, [file1, file2])
|
||||
|
||||
expect(createNode).toHaveBeenCalledTimes(2)
|
||||
expect(createNode).toHaveBeenNthCalledWith(1, mockCanvas, 'LoadImage')
|
||||
@@ -216,10 +196,7 @@ describe('pasteImageNodes', () => {
|
||||
})
|
||||
|
||||
it('should handle empty file list', async () => {
|
||||
const result = await pasteImageNodes(
|
||||
mockCanvas as unknown as LGraphCanvas,
|
||||
[]
|
||||
)
|
||||
const result = await pasteImageNodes(mockCanvas, [])
|
||||
|
||||
expect(createNode).not.toHaveBeenCalled()
|
||||
expect(result).toEqual([])
|
||||
@@ -238,7 +215,7 @@ describe('usePaste', () => {
|
||||
|
||||
it('should handle image paste', async () => {
|
||||
const mockNode = createMockNode()
|
||||
vi.mocked(createNode).mockResolvedValue(mockNode as unknown as LGraphNode)
|
||||
vi.mocked(createNode).mockResolvedValue(mockNode)
|
||||
|
||||
usePaste()
|
||||
|
||||
@@ -255,9 +232,7 @@ describe('usePaste', () => {
|
||||
|
||||
it('should handle audio paste', async () => {
|
||||
const mockNode = createMockNode()
|
||||
vi.mocked(LiteGraph.createNode).mockReturnValue(
|
||||
mockNode as unknown as LGraphNode
|
||||
)
|
||||
vi.mocked(LiteGraph.createNode).mockReturnValue(mockNode)
|
||||
|
||||
usePaste()
|
||||
|
||||
@@ -302,11 +277,11 @@ describe('usePaste', () => {
|
||||
})
|
||||
|
||||
it('should use existing image node when selected', () => {
|
||||
const mockNode = {
|
||||
const mockNode = createMockLGraphNode({
|
||||
is_selected: true,
|
||||
pasteFile: vi.fn(),
|
||||
pasteFiles: vi.fn()
|
||||
} as unknown as Partial<LGraphNode> as LGraphNode
|
||||
})
|
||||
mockCanvas.current_node = mockNode
|
||||
vi.mocked(isImageNode).mockReturnValue(true)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user