feat: strongly typed props when render vue component#1773
Conversation
📝 WalkthroughWalkthroughMaizzleConfig is made generic over a TProps type parameter, allowing the props field to be strongly typed. The render() function gains overloads that derive config prop typing from a rendered Vue component via ComponentProps. A new dependency and a test validating typed rendering were also added. ChangesTyped Props for render()
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)Not applicable — the changes are type-system enhancements and a test addition without multi-component runtime interactions warranting a sequence diagram. Suggested labels: enhancement, typescript Suggested reviewers: maizzle-maintainers 🐰 A prop, a type, a helper small, 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/render/index.ts`:
- Around line 26-42: The overload split in render is rejecting union-typed
callers, so add a union-compatible overload for render that accepts template as
string | Component (or restore the broader signature) while keeping the existing
string and generic Component overloads. Make sure the new signature is alongside
the render function declarations so TypeScript can resolve callers whose
template variable is typed as a union.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 41946957-594e-4746-a63c-ff0c108bdaea
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (4)
package.jsonsrc/render/index.tssrc/tests/render/props.test.tssrc/types/config.ts
| export async function render<TComponent extends Component>( | ||
| component: TComponent, | ||
| config?: Partial<MaizzleConfig<ComponentProps<TComponent>>>, | ||
| ): Promise<RenderResult>; | ||
|
|
||
| /** | ||
| * Render a Vue SFC email template to a fully-transformed HTML string. | ||
| * Accepts a file path or a raw SFC source string. | ||
| */ | ||
| export async function render( | ||
| template: string | Component, | ||
| template: string, | ||
| config?: Partial<MaizzleConfig>, | ||
| ): Promise<RenderResult>; | ||
|
|
||
| export async function render<TComponent extends Component>( | ||
| template: string | TComponent, | ||
| config?: Partial<MaizzleConfig<ComponentProps<TComponent>>>, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for render() call sites that might pass a union-typed template variable
rg -nP -C4 '\brender\s*\(' src --type=ts -g '!**/tests/**'Repository: maizzle/framework
Length of output: 9298
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the public render overloads, the Component type, and any call sites/usages
sed -n '1,140p' src/render/index.ts
printf '\n--- Component type ---\n'
rg -n "export (type|interface) Component|type Component|interface Component" src -g '*.ts'
printf '\n--- render() call sites/usages ---\n'
rg -n "\brender\s*\(" src test tests examples docs -g '*.ts' -g '*.tsx' -g '*.js' -g '*.mjs' -g '*.cjs' -g '*.md'
printf '\n--- union-typed candidates near render calls ---\n'
rg -n -C 2 ":\s*string\s*\|\s*Component|:\s*Component\s*\|\s*string|as\s*string\s*\|\s*Component|as\s*Component\s*\|\s*string" src test tests examples docs -g '*.ts' -g '*.tsx'Repository: maizzle/framework
Length of output: 42280
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for explicit union-typed template variables that could hit the overload gap
rg -n -C 2 "string\s*\|\s*Component|Component\s*\|\s*string" src src/tests -g '*.ts' -g '*.tsx'
printf '\n--- render() call sites with local template variables ---\n'
rg -n -C 2 "const\s+\w+\s*=\s*.*\n.*\brender\s*\(\s*\w+\s*[,)]" src src/tests -g '*.ts' -g '*.tsx'Repository: maizzle/framework
Length of output: 1230
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find explicit union-typed variables/usages relevant to render()
rg -n -C 2 "string\s*\|\s*Component|Component\s*\|\s*string" src src/tests -g '*.ts' -g '*.tsx' || true
printf '\n--- render() calls with non-literal arguments ---\n'
rg -n -C 1 "\brender\s*\(\s*[A-Za-z_][A-Za-z0-9_]*\s*[,)]" src src/tests -g '*.ts' -g '*.tsx' || trueRepository: maizzle/framework
Length of output: 3524
Keep a union-compatible overload. The split overloads reject callers whose template variable is typed string | Component, so existing TypeScript consumers with a union-typed template will stop compiling. Add an overload that accepts the union directly, or keep the previous broad signature.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/render/index.ts` around lines 26 - 42, The overload split in render is
rejecting union-typed callers, so add a union-compatible overload for render
that accepts template as string | Component (or restore the broader signature)
while keeping the existing string and generic Component overloads. Make sure the
new signature is alongside the render function declarations so TypeScript can
resolve callers whose template variable is typed as a union.
This pull request enhances type safety and flexibility when rendering Vue components by improving how props are typed and passed to components. The changes introduce generic typing for the
renderfunction and theMaizzleConfiginterface, ensuring that props are strongly typed throughout the rendering process. Additionally, a new test verifies that props are correctly passed to strongly typed components.Type safety and API improvements:
renderfunction insrc/render/index.tsnow supports generic typing for Vue components, allowing props to be strongly typed usingComponentProps<TComponent>. This ensures better type inference and developer experience when rendering components. [1] [2]MaizzleConfiginterface insrc/types/config.tsis now generic, enabling thepropsfield to be typed according to the component's expected props rather than always beingRecord<string, any>. [1] [2]Dependency updates:
vue-component-type-helperspackage topackage.jsonto provide improved type utilities for Vue component props.Testing:
src/tests/render/props.test.tsto verify that props are correctly passed to a strongly typed Vue component, ensuring the new generic typing works as intended. [1] [2]Summary by CodeRabbit