In the previous post, we talked about how to extend props from a base component to keep your Vue code clean and reusable.
Now, let's take it one step further: what if a component needs to combine props from multiple sources?
Instead of merging everything manually, you can compose props by combining interfaces in TypeScript.
Letβs see how.
Why combine interfaces?
Sometimes a component needs different sets of props:
- Clickable behavior (like
onClick
) - Styling options (like
color
,size
) - Accessibility features (like
aria-label
)
Instead of stuffing everything into one giant interface, you can build small pieces and combine them when needed.
Step 1: define small, focused interfaces
First, create small, single-purpose interfaces:
// props/clickable.ts
export interface ClickableProps {
onClick?: () => void;
}
// props/stylable.ts
export interface StylableProps {
color?: string;
size?: 'small' | 'medium' | 'large';
}
Each one is focused and easy to understand.
Step 2: combine them for your component
Now, you can combine them into a full props definition:
<!-- FancyButton.vue -->
<script setup lang="ts">
import type { ClickableProps } from '@/props/clickable.ts';
import type { StylableProps } from '@/props/stylable.ts';
interface FancyButtonProps extends ClickableProps, StylableProps {
label: string;
}
const props = defineProps<FancyButtonProps>();
</script>
<template>
<button
:style="{ color: props.color, fontSize: props.size === 'large' ? '20px' : '14px' }"
@click="props.onClick"
>
{{ props.label }}
</button>
</template>
β
FancyButton
automatically has onClick
, color
, size
, and label
β no duplication!
β
You can reuse ClickableProps
and StylableProps
in other components too.
Why This Pattern Rocks
- Separation of concerns: Small interfaces are easier to understand and document.
- Flexibility: Compose different capabilities depending on the component.
- Scalability: As your app grows, it's easy to create new combinations without rewriting everything.
- TypeScript support: Full intellisense and type checking out of the box.
Quick Example
Want to create a LinkButton
that is clickable and stylable?
You already have everything you need β just extend both!
interface LinkButtonProps extends ClickableProps, StylableProps {
href: string;
}
No duplication. No confusion. Just clean code.
Conclusion
Combining multiple prop interfaces is a simple but powerful TypeScript technique for Vue 3 projects.
It helps you keep your components modular, consistent, and easy to maintain β especially as your design system grows.
Whenever you find a prop group that could be reused, break it out into its own interface and compose as needed.
Your future self (and your teammates) will thank you!
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.