-
Notifications
You must be signed in to change notification settings - Fork 452
Description
[Bug]: z.lazy() in subgraph schema breaks TypeScript type inference requiring 'as any' casts
Custom Node Testing
- I have disabled all custom nodes and confirmed this bug is not related to custom nodes
ComfyUI Frontend Version
1.25.3+
Expected Behavior
When accessing graphData.definitions.subgraphs in TypeScript, the type system should correctly infer that each subgraph has properties like nodes, links, etc. (inherited from zComfyWorkflow1 via .extend()), without requiring as any[] type casting.
Actual Behavior
The z.lazy() wrapper in the subgraph schema definition breaks TypeScript's type inference. When iterating over graphData.definitions.subgraphs, TypeScript doesn't recognize the inherited properties, forcing developers to use as any[] to access properties like nodes:
// Current code requires 'as any[]'
for (const subgraph of graphData.definitions.subgraphs as any[]) {
if (subgraph.nodes) { // TypeScript doesn't know about 'nodes' without the cast
processNodesRecursively(subgraph.nodes, subgraph.name || subgraph.id)
}
}Steps to Reproduce
- Open
src/services/workflowService.tsor any file that processes workflow data - Try to access
graphData.definitions?.subgraphsand iterate over it - Try to access
.nodesproperty on a subgraph without type casting - TypeScript will show error that property 'nodes' doesn't exist
Debug Logs
TypeScript error without the as any[] cast:
Property 'nodes' does not exist on type...
Browser Logs
N/A - This is a compile-time TypeScript issue
Setting JSON
N/A - This is a development/type system issue
Other Information
Root Cause:
The schema uses a complex z.lazy() wrapper to handle circular references (subgraphs can contain subgraphs):
definitions: z
.object({
subgraphs: z.lazy(
(): z.ZodArray<
z.ZodType<
SubgraphDefinitionBase<ComfyWorkflow1BaseInput>,
z.ZodTypeDef,
SubgraphDefinitionBase<ComfyWorkflow1BaseInput>
>,
'many'
> => zSubgraphDefinition.array()
)
})
.optional()The verbose generic type annotation in the lazy function appears to confuse TypeScript's type inference.
Why z.lazy() is needed:
zSubgraphDefinitionextendszComfyWorkflow1- It can contain nested
definitions.subgraphs(recursive structure) - Without
z.lazy(), we get circular reference errors at the type level
Impact:
- Developers must use
as any[]throughout the codebase when working with subgraphs - Loss of type safety and IntelliSense for subgraph properties
- Makes the code harder to maintain and refactor
Potential Solutions:
- Simplify the
z.lazy()type annotation - Create explicit helper types for better inference
- Use a different approach to handle the circular reference
- Add type assertion helpers that maintain safety while improving DX
┆Issue is synchronized with this Notion page by Unito