MeWrite Docs

Vue: definePropsで外部ファイルの型をインポートできない

Vue 3のscript setupでdefinePropsに外部インターフェースを使用した際のエラー

概要

Vue 3の<script setup>構文でdefinePropsを使用する際、外部ファイルからインポートしたインターフェースを型引数として渡すとコンパイルエラーが発生する問題です。Vue 3.3以降で解決されました。

エラーメッセージ

[@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.

原因

  1. コンパイラの制限: Vue 3.2以前のSFCコンパイラは、外部ファイルの型を解決できなかった
  2. 型情報の欠落: コンパイル時に外部ファイルの型情報にアクセスできない
  3. マクロの制約: definePropsはコンパイラマクロであり、ランタイムではなくコンパイル時に処理される

解決策

1. Vue 3.3以上にアップグレード(推奨)

1
npm install vue@latest

Vue 3.3以降では外部型のインポートがサポートされています。

1
2
3
4
5
<script setup lang="ts">
import type { UserProps } from './types';

defineProps<UserProps>();
</script>

2. 同一ファイル内で型を定義(Vue 3.2以前)

1
2
3
4
5
6
7
8
<script setup lang="ts">
interface UserProps {
  name: string;
  age: number;
}

defineProps<UserProps>();
</script>

3. withDefaultsと組み合わせる

1
2
3
4
5
6
7
8
<script setup lang="ts">
import type { UserProps } from './types';

const props = withDefaults(defineProps<UserProps>(), {
  name: 'Guest',
  age: 0
});
</script>

4. ランタイム宣言を使用(型安全性は低下)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<script setup lang="ts">
import { PropType } from 'vue';
import type { User } from './types';

defineProps({
  user: {
    type: Object as PropType<User>,
    required: true
  }
});
</script>

5. 型を再エクスポート

1
2
3
4
5
// types/index.ts
export interface UserProps {
  name: string;
  age: number;
}
1
2
3
4
5
6
<script setup lang="ts">
// Vue 3.3+
import type { UserProps } from '@/types';

defineProps<UserProps>();
</script>

6. defineEmitsでも同様

1
2
3
4
5
6
<script setup lang="ts">
import type { Emits } from './types';

// Vue 3.3+
defineEmits<Emits>();
</script>

よくある間違い

  • Vue 3.2以前で外部型を使おうとする
  • importではなくimport typeを使わない(ランタイムインポートになる)
  • 複雑な型演算(Conditional Types等)を直接使用する

関連エラー

参考リンク

Vue.js の他のエラー

最終更新: 2025-12-13