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!