When you're building Vue 3 apps with TypeScript, defining props carefully is important. But if you're not careful, you might find yourself copy-pasting the same props over and over across components.
A much better way is to extend prop types. This keeps your components simple, consistent, and type-safe.
Let's walk through a clean, simple example.
The problem
Suppose you have a basic button component with a few common props like label
and disabled
.
Later, you want to build a specialized button, like a "LinkButton", that behaves a little differently but still needs all the base props.
Instead of copying all the props, you can extend them.
Step 1: Create the BaseButton
<!-- BaseButton.vue -->
<script setup lang="ts">
export interface BaseButtonProps {
label: string;
disabled?: boolean;
}
const props = defineProps<BaseButtonProps>();
</script>
<template>
<button :disabled="props.disabled">{{ props.label }}</button>
</template>
This is a simple button that takes a label
and an optional disabled
state.
Step 2: Create a specialized Button by extending props
Now, you want a LinkButton
that acts like a button but also takes a href
prop (for the link URL).
You can extend the base props like this:
<!-- LinkButton.vue -->
<script setup lang="ts">
import BaseButton, { BaseButtonProps } from './BaseButton.vue';
interface LinkButtonProps extends BaseButtonProps {
href: string;
}
const props = defineProps<LinkButtonProps>();
</script>
<template>
<a :href="props.href">
<BaseButton v-bind="props" />
</a>
</template>
✅ All the BaseButtonProps
(label
, disabled
) are automatically included.
✅ LinkButton
adds its own href
prop.
✅ You don't have to repeat or duplicate the base props.
Why this pattern is powerful
- No duplication: You define common props once and reuse them everywhere.
- Type safety: If you change
BaseButtonProps
, the changes propagate automatically. - Clear code: Each specialized component focuses only on its differences.
- Easy maintenance: Your components stay small, predictable, and consistent.
Quick Visual
Without Extending | With Extending |
---|---|
Repeat all props manually | Inherit props automatically |
High risk of mistakes | Compiler catches missing/invalid props |
Hard to maintain over time | Easy to update in one place |
Conclusion
If you're building reusable Vue 3 components with TypeScript, extending your prop interfaces is one of the simplest and best ways to keep your code clean, scalable, and easy to maintain.
Whenever you notice yourself copying prop definitions between components — stop and think:
➡️ Should I extend instead?
Most of the time, the answer will be yes.
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.