💡

TypeScriptでプロパティが存在しないことを保証する型定義の方法 ?: never の使い方

に公開

TypeScriptである状態ではプロパティが"存在しない"ことを保証する型定義の方法です。

たとえば、ユーザーが「ゲスト」か「メンバー」かによってメールアドレスを持つ・持たないが決まるとします。

type GuestUser = {
  role: "guest";
  email?: never; // ← ゲストはメールアドレスを持たない
};

type MemberUser = {
  role: "member";
  email: string; // ← メンバーは必ずメールアドレスを持つ
};

type User = GuestUser | MemberUser;

// ✅ OK: メンバーは email がある
const member: User = { role: "member", email: "a@example.com" };

// ✅ OK: ゲストは email がない
const guest: User = { role: "guest" };

// ❌ NG: ゲストなのに email がある
const wrong: User = { role: "guest", email: "x@example.com" };
// Error: Type '{ role: "guest"; email: string; }' is not assignable to type 'User'.

email?: never によって、「ゲストは email を持ってはいけない」ことが型で守られます。

email: never => email は必須だが、値はあり得ない(常にエラー、どんな値も代入不可)
email?: never => email がなければOK、存在したらエラー

という違いになります。

type A = { prop: never };
type B = { prop?: never };

const a1: A = {};                   // ❌ prop が必須
const a2: A = { prop: undefined };  // ❌ never に undefined は代入できない

const b1: B = {};                   // ✅ OK(prop なし)
const b2: B = { prop: undefined };  // ❌ strictモードではNG(存在扱い)

Discussion