[[TypeScript]]の[[Mapped Types]]で[[プロパティ (TypeScript)|プロパティ]]に修飾子を付与したり外したりできる機能。
## サポートしている修飾子
| 修飾子 | 意味 |
| ---------- | --------------------------------------------------------------- |
| `readonly` | [[読み取り専用プロパティ (TypeScript)\|読み取り専用プロパティ]] |
| `?` | [[オプショナルプロパティ]] |
修飾子の位置は普段使う場合と同じ位置。
`readonly`なら名前の前。
```ts
interface Human {
id: number
name: string
}
type HasHumanProperties = {
readonly [K in keyof Human]: boolean
}
const p: HasHumanProperties = {
id: true,
name: false,
}
p.id = false
// Cannot assign to 'id' because it is a read-only property.(2540)
```
<button class="playground"><a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgBIFcC2cTIN4CwAUMqcsACYBcyIWARtMQJAhyYQ0DOYUoA5sQC+xYmACeABxSo4XDNhAAFKAHtpUMMAhdkAXnwsoEOBVUgANuOQBtANLlcAawjjVMNFhwBdGvVWqFiYgwqJECOY8yJI0svJeymoaWjr6hiRklDS86BAANMRktOycyPAWXPmhRMSSAHSUaeWVxAD0rcgAwjggqmDIclzA-LhgqsgA5JQTyIwIcOiV5P3AunDIxqYAtOZW0UnQEnUAFABMAKwALAAMAJTEQA">Playground</a></button>
`?`なら名前の後。
```ts
interface Human {
id: number
name: string
}
type HasHumanProperties = {
[K in keyof Human]?: boolean
}
const p: HasHumanProperties = {
name: false,
}
```
<button class="playground"><a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgBIFcC2cTIN4CwAUMqcsACYBcyIWARtMQJAhyYQ0DOYUoA5sQC+xYmACeABxSo4XDNhAAFKAHtpUMMAhdkAXnwsA2gGlyuANYRxqmGiw4AugH4a9VaoA2EHMNFEEVRAeZEkaWXkHZTUNLR19QxIyNg4aeE8uCAAaYSA">Playground</a></button>
## 修飾子の除去
修飾子の直前に`-`をつけると、外すこともできる。
```ts
interface Human {
readonly id: number;
name?: string;
}
const p: Human = {
id: 100,
};
p.id = -1;
// Cannot assign to 'id' because it is a read-only property.(2540)
// ----------------------------------------------------------------
type HasHumanProperties = {
-readonly [K in keyof Human]-?: boolean;
};
const r: HasHumanProperties = {
id: true,
};
// Property 'name' is missing in type '{ id: true; }' but required in type 'HasHumanProperties'.(2741)
r.id = false;
```
<button class="playground"><a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgBIFcC2cTIN4BQyyUEcAJgPYgA2AnssOQFzIhYBG0A3EW3JggB+VgGcwUUAHNeAXwIEE1ccgAOrDNlwBefHyasAjAAZjAGgKzeqgHRNkugLSHeAelfIAwjhCUwyOFFRYClcMEpkAHImSOQuBDh0URRgf2BRAJIyckdqejUoSlVoMDobAAoAJgBWABZjAEoFd2RHNvaOzq7unt6+3oVS4rRAzRwABULiqDBgCAzdQmJHUgo8hgBtAGlGXABrCDpKGDQsHABdRxE4ykoaMhA5XkVlfygNUbOQSaKSuYW9MQDMgJOgIBYrAQWj9pqUoiABBBYulkJh0sEQFJdiC6MNInhGCwQVAwdxkLJYhx0G8IABHdDAUjkbFDFCRVCfLQwv7zSIVSoAdlqhiaBCgdmZungNGSvCAA">Playground</a></button>