Skip to content

Instantly share code, notes, and snippets.

@yukikim
Last active November 17, 2024 17:02
Show Gist options
  • Save yukikim/cf020c4fd3be90b1a66faa4317b45dee to your computer and use it in GitHub Desktop.
Save yukikim/cf020c4fd3be90b1a66faa4317b45dee to your computer and use it in GitHub Desktop.
特定のプロパティを使用して値を検証

TypeScriptで、特定のプロパティを使用して値を検証し、結果をbooleanとして取得するには、関数を定義して実現します。このとき、型安全性を確保しながら特定のプロパティを検証するために、keyofやインデックス型クエリを使用します。

以下に具体的な例を示します。

例: プロパティ値の検証

interface User {
  id: number;
  name: string;
  email: string;
}

// ユーザーのデータを検証する関数
function validateProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): boolean {
  return obj[key] === value;
}

// 使用例
const user: User = { id: 1, name: "Alice", email: "[email protected]" };

// 検証
const isNameAlice = validateProperty(user, "name", "Alice"); // true
const isEmailBob = validateProperty(user, "email", "[email protected]"); // false

console.log(isNameAlice); // true
console.log(isEmailBob);  // false

for(const key in user) {
  console.log(key as any, user[key as keyof typeof user])
  console.log(validateProperty(user, (key as keyof typeof user), user[key as keyof typeof user]))
  console.log(typeof (user[key as keyof typeof user]))
}
interface Student {
  name: string;
  grade: number;
}
 
// Student型かを判定する型ガード関数
function isStudent(value: unknown): value is Student {
  // 値がオブジェクトであるかの判定
  if (typeof value !== "object" || value === null) {
    return false;
  }
  const { name, grade } = value as Record<keyof Student, unknown>;
  // nameプロパティーが文字列型かを判定
  if (typeof name !== "string") {
    return false;
  }
  // gradeプロパティーが数値型かを判定
  if (typeof grade !== "number") {
    return false;
  }
  return true;
}

上のisStudent関数をinstanceofの代わりに用いる

const tom: object = { name: "Tom", grade: 2 };
if (isStudent(tom)) {
  tom;
}

解説

  1. keyofを使用して型制約を指定

    • K extends keyof Tにより、key引数がオブジェクトTのプロパティキーであることを保証します。
  2. 型安全な値検証

    • value引数はT[K]型であるため、指定されたキーの値と型が一致しているかチェックされます。
  3. 汎用性の高い関数

    • この関数は任意のオブジェクトとプロパティに対して使用でき、型エラーを防ぐことができます。

特定のプロパティだけを検証したい場合

特定のプロパティを事前に決めておく場合は、関数をカスタマイズできます。

function isUserNameAlice(user: User): boolean {
  return user.name === "Alice";
}

console.log(isUserNameAlice(user)); // true

このように、検証内容を特化させることで、コードの可読性を高めることもできます。

zodはオブジェクトの構造をチェックするライブラリ

import z from "zod";
 
// zodによるスキーマの定義
const studentSchema = z.object({
  name: z.string(),
  grade: z.number(),
});
// インターフェースの型を導出
type Student = z.infer<typeof studentSchema>;
// 型ガード関数
function isStudent(value: unknown): value is Student {
  return studentSchema.safeParse(value).success;
}
// 型の判定
const tom: object = { name: "Tom", grade: 2 };
if (isStudent(tom)) {
  tom;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment