1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

typeofとkeyofについて

Posted at

業務でtypeofとkeyofが出てきたので、備忘録として残しておきます。
(typescriptの型関連が難しい......)

typeofとは

typeof を使うことで、オブジェクトや変数の型そのものが取得できます。

使用例


const person = {
  name: "Alice",
  age: 30,
};

// `person` と同じ構造の型を定義
type PersonType = typeof person;

const anotherPerson: PersonType = {
  name: "Bob",
  age: 25,
};

ポイント:

typeof personperson オブジェクトの型 { name: string; age: number } を取得します。
こうすることで、personに新しいプロパティを追加しても、PersonTypeを自動的に更新できるので、変更に強いコードとなります。

keyofとは

keyofをつかうことで、オブジェクト型のキー(プロパティ名)を文字列リテラル型として取得できます。(型のみで使用可能)

使用例


type Example = {
  a: number;
  b: string;
  c: boolean;
};

// keyof を使用
type Keys = keyof Example;
// Keys は "a" | "b" | "c" というリテラル型

const obj: Example = { a: 1, b: "hello", c: true };

// 型安全なプロパティアクセス
const getValue = (key: Keys): Example[Keys] => obj[key];

const valueA = getValue("a"); // OK: number型
const valueB = getValue("b"); // OK: string型
// getValue("d"); // エラー: '"d"' は 'Keys' に割り当てられません

ポイント:

keyof ExampleExample 型のすべてのプロパティ名をリテラル型として取得します。
keyofを使うと、プロパティ名以外の無効なキーにアクセスしようとするとエラーになるため、型安全な操作が可能となります。

typeof と keyof を組み合わせた場合

以下はオブジェクトのプロパティ名と値を利用した例です。


const Status = {
  SUCCESS: "success",
  ERROR: "error",
  LOADING: "loading",
} as const;

// typeof と keyof を使って型を生成
// type StatusValue = (typeof Status)[keyof typeof Status] でも同じ
type StatusKey = keyof typeof Status; // "SUCCESS" | "ERROR" | "LOADING"
type StatusValue = (typeof Status)[StatusKey]; // "success" | "error" | "loading"

// 型安全な関数
function handleStatus(status: StatusValue) {
  if (status === "success") {
    console.log("Operation was successful!");
  } else if (status === "error") {
    console.log("An error occurred.");
  } else if (status === "loading") {
    console.log("Still loading...");
  }
}

// 使用例
handleStatus("success"); // OK
// handleStatus("unknown"); // エラー

ポイント:

keyof typeof Statusでキーリテラル型("SUCCESS" | "ERROR" | "LOADING")を取得します。
次に、(typeof Status)[keyof typeof Status]で値リテラル型("success" | "error" | "loading")を取得します。

as const の補足説明

const Status = {
  SUCCESS: "success",
  ERROR: "error",
  LOADING: "loading",
} as const;

as const の役割:

  • Status を読み取り専用(readonly)にする。
  • 各プロパティの型を "success", "error", "loading" のリテラル型に変換する。
     (as const がない場合、Status のプロパティは一般的な string 型と解釈されてしまうので、リテラル型の恩恵を受けられない。)

まとめ

  • typeof:
    • 変数やオブジェクトの型を取得して再利用できる
    • 型定義を重複せず、変更に強いコードが書ける
  • keyof:
    • オブジェクト型のすべてのキーをリテラル型として取得する
    • 型安全なプロパティアクセスが可能となる
  • typeofkeyof の組み合わせ:
    • typeofで型を取得して、keyofでプロパティ名をリテラル型で取得することで、型安全なキーや値の操作が可能となる

使用方法はなんとなくわかったけど、実際に使いこなせるのか:cry:
実務経験をたくさん積みたい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?