fix(types): remove @ts-expect-error in components and composables

Amp-Thread-ID: https://ampcode.com/threads/T-019bafc7-9674-769c-bfea-dd60aa6c47a7
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
DrJKL
2026-01-11 17:48:51 -08:00
parent 4fd516750a
commit cf6637965d
16 changed files with 91 additions and 84 deletions

View File

@@ -92,18 +92,16 @@ const colorOptions = [
const defaultIcon = iconOptions.find(
(option) => option.value === nodeBookmarkStore.defaultBookmarkIcon
)
) ?? { name: '', value: '' }
// @ts-expect-error fixme ts strict error
const selectedIcon = ref<{ name: string; value: string }>(defaultIcon)
const finalColor = ref(
props.initialColor || nodeBookmarkStore.defaultBookmarkColor
)
const resetCustomization = () => {
// @ts-expect-error fixme ts strict error
selectedIcon.value =
iconOptions.find((option) => option.value === props.initialIcon) ||
iconOptions.find((option) => option.value === props.initialIcon) ??
defaultIcon
finalColor.value =
props.initialColor || nodeBookmarkStore.defaultBookmarkColor

View File

@@ -13,8 +13,10 @@ describe('EditableText', () => {
app.use(PrimeVue)
})
// @ts-expect-error fixme ts strict error
const mountComponent = (props, options = {}) => {
const mountComponent = (
props: { modelValue: string; isEditing: boolean },
options = {}
) => {
return mount(EditableText, {
global: {
plugins: [PrimeVue],
@@ -65,8 +67,7 @@ describe('EditableText', () => {
})
await wrapper.findComponent(InputText).trigger('blur')
expect(wrapper.emitted('edit')).toBeTruthy()
// @ts-expect-error fixme ts strict error
expect(wrapper.emitted('edit')[0]).toEqual(['Test Text'])
expect(wrapper.emitted('edit')?.[0]).toEqual(['Test Text'])
})
it('cancels editing on escape key', async () => {
@@ -124,8 +125,7 @@ describe('EditableText', () => {
// Trigger blur that happens after enter
await enterWrapper.findComponent(InputText).trigger('blur')
expect(enterWrapper.emitted('edit')).toBeTruthy()
// @ts-expect-error fixme ts strict error
expect(enterWrapper.emitted('edit')[0]).toEqual(['Saved Text'])
expect(enterWrapper.emitted('edit')?.[0]).toEqual(['Saved Text'])
// Test Escape key cancels changes with a fresh wrapper
const escapeWrapper = mountComponent({

View File

@@ -44,12 +44,13 @@ const {
const emit = defineEmits(['edit', 'cancel'])
const inputValue = ref<string>(modelValue)
const inputRef = ref<InstanceType<typeof InputText> | undefined>()
const inputRef = ref<
(InstanceType<typeof InputText> & { $el?: HTMLElement }) | undefined
>()
const isCanceling = ref(false)
const blurInputElement = () => {
// @ts-expect-error - $el is an internal property of the InputText component
inputRef.value?.$el.blur()
inputRef.value?.$el?.blur()
}
const finishEditing = () => {
// Don't save if we're canceling
@@ -74,15 +75,14 @@ watch(
if (newVal) {
inputValue.value = modelValue
await nextTick(() => {
if (!inputRef.value) return
const el = inputRef.value?.$el
if (!el || !(el instanceof HTMLInputElement)) return
const fileName = inputValue.value.includes('.')
? inputValue.value.split('.').slice(0, -1).join('.')
: inputValue.value
const start = 0
const end = fileName.length
// @ts-expect-error - $el is an internal property of the InputText component
const inputElement = inputRef.value.$el
inputElement.setSelectionRange?.(start, end)
el.setSelectionRange?.(start, end)
})
}
},

View File

@@ -116,17 +116,16 @@ const fileSize = computed(() =>
)
const { copyToClipboard } = useCopyToClipboard()
const electronDownloadStore = useElectronDownloadStore()
// @ts-expect-error fixme ts strict error
const [savePath, filename] = props.label.split('/')
const [savePath = '', filename = ''] = props.label?.split('/') ?? []
electronDownloadStore.$subscribe((_, { downloads }) => {
const download = downloads.find((download) => props.url === download.url)
const foundDownload = downloads.find((download) => props.url === download.url)
if (download) {
// @ts-expect-error fixme ts strict error
downloadProgress.value = Number((download.progress * 100).toFixed(1))
// @ts-expect-error fixme ts strict error
status.value = download.status
if (foundDownload) {
downloadProgress.value = Number(
((foundDownload.progress ?? 0) * 100).toFixed(1)
)
status.value = foundDownload.status ?? null
}
})

View File

@@ -61,8 +61,8 @@ describe('TreeExplorerTreeNode', () => {
expect(wrapper.findComponent(EditableText).props('modelValue')).toBe(
'Test Node'
)
// @ts-expect-error fixme ts strict error
expect(wrapper.findComponent(Badge).props()['value'].toString()).toBe('3')
const badgeValue = wrapper.findComponent(Badge).props()['value']
expect(String(badgeValue)).toBe('3')
})
it('makes node label editable when renamingEditingNode matches', async () => {

View File

@@ -14,8 +14,6 @@ vi.mock('@/stores/systemStatsStore', () => ({
}))
const createMockNode = (type: string, version?: string): LGraphNode =>
// @ts-expect-error - Creating a partial mock of LGraphNode for testing purposes.
// We only need specific properties for our tests, not the full LGraphNode interface.
({
type,
properties: { cnr_id: 'comfy-core', ver: version },
@@ -28,7 +26,7 @@ const createMockNode = (type: string, version?: string): LGraphNode =>
mode: 0,
inputs: [],
outputs: []
})
}) as unknown as LGraphNode
describe('MissingCoreNodesMessage', () => {
const mockSystemStatsStore = {
@@ -41,9 +39,9 @@ describe('MissingCoreNodesMessage', () => {
// Reset the mock store state
mockSystemStatsStore.systemStats = null
mockSystemStatsStore.refetchSystemStats = vi.fn()
// @ts-expect-error - Mocking the return value of useSystemStatsStore for testing.
// The actual store has more properties, but we only need these for our tests.
useSystemStatsStore.mockReturnValue(mockSystemStatsStore)
vi.mocked(useSystemStatsStore).mockReturnValue(
mockSystemStatsStore as unknown as ReturnType<typeof useSystemStatsStore>
)
})
const mountComponent = (props = {}) => {

View File

@@ -39,11 +39,13 @@ const onConfirm = () => {
useDialogStore().closeDialog()
}
const inputRef = ref<InstanceType<typeof InputText> | undefined>()
const inputRef = ref<
(InstanceType<typeof InputText> & { $el?: HTMLElement }) | undefined
>()
const selectAllText = () => {
if (!inputRef.value) return
// @ts-expect-error - $el is an internal property of the InputText component
const inputElement = inputRef.value.$el
inputElement.setSelectionRange(0, inputElement.value.length)
const el = inputRef.value?.$el
if (el instanceof HTMLInputElement) {
el.setSelectionRange(0, el.value.length)
}
}
</script>

View File

@@ -194,7 +194,9 @@ const selectedCommandData = ref<ICommandData | null>(null)
const editDialogVisible = ref(false)
const newBindingKeyCombo = ref<KeyComboImpl | null>(null)
const currentEditingCommand = ref<ICommandData | null>(null)
const keybindingInput = ref<InstanceType<typeof InputText> | null>(null)
const keybindingInput = ref<
(InstanceType<typeof InputText> & { $el?: HTMLElement }) | null
>(null)
const existingKeybindingOnCombo = computed<KeybindingImpl | null>(() => {
if (!currentEditingCommand.value) {
@@ -229,8 +231,8 @@ watchEffect(() => {
if (editDialogVisible.value) {
// nextTick doesn't work here, so we use a timeout instead
setTimeout(() => {
// @ts-expect-error - $el is an internal property of the InputText component
keybindingInput.value?.$el?.focus()
const el = keybindingInput.value?.$el
if (el instanceof HTMLElement) el.focus()
}, 300)
}
})

View File

@@ -428,7 +428,7 @@ onMounted(async () => {
await newUserService().initializeIfNewUser(settingStore)
// @ts-expect-error fixme ts strict error
if (!canvasRef.value) return
await comfyApp.setup(canvasRef.value)
canvasStore.canvas = comfyApp.canvas
canvasStore.canvas.render_canvas_border = false

View File

@@ -161,15 +161,14 @@ const selectCategory = (category: string) => {
}
const getCategoryIcon = (category: string) => {
const icons = {
const icons: Record<string, string> = {
scene: 'pi pi-image',
model: 'pi pi-box',
camera: 'pi pi-camera',
light: 'pi pi-sun',
export: 'pi pi-download'
}
// @ts-expect-error fixme ts strict error
return `${icons[category]} text-base-foreground text-lg`
return `${icons[category] ?? ''} text-base-foreground text-lg`
}
const emit = defineEmits<{

View File

@@ -145,17 +145,16 @@ const renderedRoot = computed<TreeExplorerNode<ModelOrFolder>>(() => {
children,
draggable: node.leaf,
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
if (this.leaf && model) {
const provider = modelToNodeStore.getNodeProvider(model.directory)
if (provider) {
const node = useLitegraphService().addNodeOnGraph(provider.nodeDef)
// @ts-expect-error fixme ts strict error
const widget = node.widgets.find(
const addedNode = useLitegraphService().addNodeOnGraph(
provider.nodeDef
)
const widget = addedNode?.widgets?.find(
(widget) => widget.name === provider.key
)
if (widget) {
// @ts-expect-error fixme ts strict error
widget.value = model.file_name
}
}

View File

@@ -278,8 +278,7 @@ const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
}
},
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
if (this.leaf && this.data) {
useLitegraphService().addNodeOnGraph(this.data)
} else {
toggleNodeOnEvent(e, this)
@@ -336,8 +335,7 @@ const onAddFilter = async (
await handleSearch(searchQuery.value)
}
// @ts-expect-error fixme ts strict error
const onRemoveFilter = async (filterAndValue) => {
const onRemoveFilter = async (filterAndValue: SearchFilter) => {
const index = filters.value.findIndex((f) => f === filterAndValue)
if (index !== -1) {
filters.value.splice(index, 1)

View File

@@ -162,20 +162,17 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
droppable: !node.leaf,
async handleDrop(data: TreeExplorerDragAndDropData<ComfyNodeDefImpl>) {
const nodeDefToAdd = data.data.data
if (!nodeDefToAdd) return
// Remove bookmark if the source is the top level bookmarked node.
// @ts-expect-error fixme ts strict error
if (nodeBookmarkStore.isBookmarked(nodeDefToAdd)) {
// @ts-expect-error fixme ts strict error
await nodeBookmarkStore.toggleBookmark(nodeDefToAdd)
}
const folderNodeDef = node.data as ComfyNodeDefImpl
// @ts-expect-error fixme ts strict error
const nodePath = folderNodeDef.category + '/' + nodeDefToAdd.name
await nodeBookmarkStore.addBookmark(nodePath)
},
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
if (this.leaf && this.data) {
useLitegraphService().addNodeOnGraph(this.data)
} else {
toggleNodeOnEvent(e, node)
@@ -194,8 +191,9 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
}
},
async handleDelete() {
// @ts-expect-error fixme ts strict error
await nodeBookmarkStore.deleteBookmarkFolder(this.data)
if (this.data) {
await nodeBookmarkStore.deleteBookmarkFolder(this.data)
}
}
})
}

View File

@@ -94,27 +94,32 @@ describe('CurrentUserButton', () => {
})
it('toggles popover on button click', async () => {
const wrapper = mountComponent()
const wrapper = mountComponent() as VueWrapper<
InstanceType<typeof CurrentUserButton>
>
const popoverToggleSpy = vi.fn()
// Override the ref with a mock implementation
// @ts-expect-error - accessing internal Vue component vm
wrapper.vm.popover = { toggle: popoverToggleSpy }
wrapper.vm.popover = {
toggle: popoverToggleSpy
} as unknown as typeof wrapper.vm.popover
await wrapper.findComponent(Button).trigger('click')
expect(popoverToggleSpy).toHaveBeenCalled()
})
it('hides popover when closePopover is called', async () => {
const wrapper = mountComponent()
const wrapper = mountComponent() as VueWrapper<
InstanceType<typeof CurrentUserButton>
>
// Replace the popover.hide method with a spy
const popoverHideSpy = vi.fn()
// @ts-expect-error - accessing internal Vue component vm
wrapper.vm.popover = { hide: popoverHideSpy }
wrapper.vm.popover = {
hide: popoverHideSpy
} as unknown as typeof wrapper.vm.popover
// Directly call the closePopover method through the component instance
// @ts-expect-error - accessing internal Vue component vm
wrapper.vm.closePopover()
// Verify that popover.hide was called

View File

@@ -62,4 +62,6 @@ const photoURL = computed<string | undefined>(
const closePopover = () => {
popover.value?.hide()
}
defineExpose({ popover, closePopover })
</script>

View File

@@ -28,11 +28,12 @@ vi.mock('@/lib/litegraph/src/litegraph', () => ({
}
}))
// Mock Positionable objects
// @ts-expect-error - Mock implementation for testing
// Mock Positionable objects - full implementation for testing
class MockNode implements Positionable {
readonly id = 1
pos: [number, number]
size: [number, number]
readonly boundingRect: [number, number, number, number]
constructor(
pos: [number, number] = [0, 0],
@@ -40,22 +41,35 @@ class MockNode implements Positionable {
) {
this.pos = pos
this.size = size
this.boundingRect = [pos[0], pos[1], size[0], size[1]]
}
move(): void {}
snapToGrid(): boolean {
return false
}
}
class MockReroute extends Reroute implements Positionable {
// @ts-expect-error - Override for testing
override pos: [number, number]
// MockReroute - passes instanceof Reroute check
class MockReroute implements Positionable {
readonly id = 1
pos: [number, number]
size: [number, number]
readonly boundingRect: [number, number, number, number]
constructor(
pos: [number, number] = [0, 0],
size: [number, number] = [20, 20]
) {
// @ts-expect-error - Mock constructor
super()
Object.setPrototypeOf(this, Reroute.prototype)
this.pos = pos
this.size = size
this.boundingRect = [pos[0], pos[1], size[0], size[1]]
}
move(): void {}
snapToGrid(): boolean {
return false
}
}
@@ -86,7 +100,6 @@ describe('useSelectedLiteGraphItems', () => {
it('should return false for non-Reroute items', () => {
const { isIgnoredItem } = useSelectedLiteGraphItems()
const node = new MockNode()
// @ts-expect-error - Test mock
expect(isIgnoredItem(node)).toBe(false)
})
})
@@ -98,14 +111,11 @@ describe('useSelectedLiteGraphItems', () => {
const node2 = new MockNode([100, 100])
const reroute = new MockReroute([50, 50])
// @ts-expect-error - Test mocks
const items = new Set<Positionable>([node1, node2, reroute])
const filtered = filterSelectableItems(items)
expect(filtered.size).toBe(2)
// @ts-expect-error - Test mocks
expect(filtered.has(node1)).toBe(true)
// @ts-expect-error - Test mocks
expect(filtered.has(node2)).toBe(true)
expect(filtered.has(reroute)).toBe(false)
})
@@ -143,9 +153,7 @@ describe('useSelectedLiteGraphItems', () => {
const selectableItems = getSelectableItems()
expect(selectableItems.size).toBe(2)
// @ts-expect-error - Test mock
expect(selectableItems.has(node1)).toBe(true)
// @ts-expect-error - Test mock
expect(selectableItems.has(node2)).toBe(true)
expect(selectableItems.has(reroute)).toBe(false)
})
@@ -215,8 +223,7 @@ describe('useSelectedLiteGraphItems', () => {
it('getSelectedNodes should return empty array when no nodes selected', () => {
const { getSelectedNodes } = useSelectedLiteGraphItems()
// @ts-expect-error - Testing null case
app.canvas.selected_nodes = null
Object.assign(app.canvas, { selected_nodes: null })
const selectedNodes = getSelectedNodes()
expect(selectedNodes).toHaveLength(0)