0
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?

type-challenges解いてみた 初級 7-Readonly編

Last updated at Posted at 2025-02-23

問題

組み込みの型ユーティリティ`Readonly<T>`を使用せず、`T` のすべてのプロパティを読み取り専用にする型を実装します。実装された型のプロパティは再割り当てできません。

例えば:

```ts
interface Todo {
  title: string
  description: string
}

const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
}

todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
```

TypeScriptの組み込みユーティリティ型Readonlyを使用せずにすべてのプロパティを読み取り専用にする型を作成してくださいという問題です。
JSのreadonly修飾子を禁じられているわけではないのでご注意ください。(一敗)

回答

type MyReadonly<T> = {
  readonly [key in keyof T] : T[key] 
} 

初級だけありかなり単純ですね。

詳細解説

keyof T

Tのすべてのプロパティ名のユニオン型を生成します。
例えば T が { a: number, b: string } なら、keyof T は "a" | "b" になります

Mapped Types(マッピング型)

[key in keyof T]の部分は、T の各プロパティ名を取り出し、対応するプロパティを生成するための構文です。

readonly 修飾子

readonly を付けることで、オブジェクト生成後にそのプロパティが変更できなくなります。

T[key]

元の型 T の各プロパティの型がそのまま引き継がれます
例えば以下のような場合

{
  a: "aaa",
  b: "bbb",
  c: "ccc",
}

keyof Tでプロパティ名のユニオン型を生成すると "a" | "b" | "c" となり、[key in keyof T]で "a" | "b" | "c" がプロパティ名のオブジェクトが作成されます。
そして各プロパティのvalueはT[key]なので...

{
  a: `T["a"]` // -> "aaa"
  b: `T["b"]` // -> "bbb"
  c: `T["c"]` // -> "ccc"
}

と、元のオブジェクトが復元されるような形となります。

0
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
0
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?