SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ますます便利になるVue.jsの新機能を探ろう!

TypeScriptのサポートが強化されたVue3.3の新機能とは?──PropsとEmitsに関する新機能を解説【前編】

TypeScriptのサポートがアップデート! Vue3.3の新機能まとめ 前編

PropsとEmitsに関する新機能

 まず、最初に紹介するのは、新機能リストの1と2、すなわち、PropsとEmitsに関する新機能です。

Props型定義とEmits型定義のインポート

 Vueのコンポーネント間連携であるPropsとEmitを利用する際、defineProps()とdefineEmits()マクロを利用します。その際、ジェネリクスとして、Propsならば個々のPropを型定義したものを、Emitならば関数の型定義を渡します。

 この型定義に関して、これまではリスト1のように、defineProps()やdefineEmits()を実行するコンポーネント内で定義したもの、つまり、ローカルな型定義である必要がありました。

リスト1:Vue3.2以前のdefineProps()やdefineEmits()の型定義
interface Props {
  id: number;
  name: string;
  email: string;
  points: number;
}
interface Emits {
  (event: "incrementPoint", id: number): void;
}
const props = defineProps<Props>();
const emit = defineEmits<Emits>();

 これが、Vue3.3では、リスト2のように、別ファイルに記述した型定義をインポートして利用できるようになりました。これにより、PropsとEmitの型定義の再利用が可能となります。

リスト2:Vue3.3ではインポートした型定義を利用可能
import type {Props, Emits} from "@/interfacesForMacros";

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

[NOTE]マクロ

 defineProps()やdefineEmits()関数は、通常の関数とは違い、「マクロ」と呼ばれています。マクロとは、ソースコードがコンパイルされる際に別の関数などを生成することで、コンパイル後には存在しなくなる特殊な関数のことです。

新しいEmits定義

 このようにインポートできるようになったマクロ用の型定義に関して、Emitについては、さらに新しい仕組みが導入されました。これまでは、リスト2のインターフェースEmitsのように、コールシグネチャを記述する必要がありました。

 Vue3.3では、このコールシグネチャももちろん利用できますが、新たな型定義が導入されました。これは、リスト3のようになります。

リスト3:新しいEmits型定義
type Emits = {
  incrementPoint: [id: number];
};

 これまでのコールシグネチャでは引数eventのリテラル型としていたイベント名を、プロパティ名としたオブジェクトを定義します。そのプロパティの値として、これまでのコールシグネチャの第2引数以降として記述していた部分、すなわち、Emit関数の実行時に親コンポーネントにデータを渡すための引数定義をラベル付きタプルとして記述します。

 もし、引数の不要なEmit定義の場合は、リスト4のように空の配列定義とします。

リスト4:新しいEmits型定義(引数無し)
type Emits = {
  incrementPoint: [];
};

 なお、このラベル付きタプルを利用した新しいEmitsの型定義については、インターフェースとして定義するとエラーとなります。そのため、リスト3やリスト4のように、typeキーワードを利用した型定義とします。

[NOTE]ラベル付きタプル

 通常、TypeScriptのタプルは、以下のように配列の各要素に対してデータ型のみを定義します。

type BMIData = [string, number, number];

 この各要素のデータ型に、以下のように、さらに変数名のようにラベルをつけることができます。これを「ラベル付きタプル」といいます。

type BMIData = [name: string, height: number, weight: number];

インポートした型定義の拡張も可能

 このPropsやEmitsのマクロ用の型定義に関しては、インポートした型を拡張して利用することも、Vue3.3で可能となりました。例えば、リスト5のようなコードです。

リスト5:インポートしたProps型定義を拡張して利用可能
import type {Props as PropsOrgn, Emits} from "@/interfacesForMacros";  // (1)

interface Props extends PropsOrgn {  // (2)
  note?: string;  // (3)
}
const props = defineProps<Props>();

 リスト4との違いは、interfacesForMacros.tsからインポートしたインターフェースPropsをPropsOrgnとし、(2)でそのPropsOrgnを拡張したインターフェースPropsを定義し、(3)のnoteプロパティを追加しています。

次のページ
PropsとEmitsに関する実験的な新機能

この記事は参考になりましたか?

ますます便利になるVue.jsの新機能を探ろう!連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/18306 2023/09/20 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー