映射类型 
核心语法 
TypeScript 的**映射类型(Mapped Types)**本质上就是“批量生成接口”的语法糖,
ts
[ K in 键合集 ] : 值类型in把右侧的联合类型逐一枚举出来,当成键名
ts
type Keys = 'a' | 'b' | 'c'
type T = { [K in Keys]: number }
// 相当于手写:
// { a: number; b: number; c: number }修饰符操作符 
在 TypeScript 的映射类型里,+ 和 - 是修饰符操作符,专门用来增删某个属性修饰语(readonly 或 ?)。 它们只能出现在映射类型的键签名那一行,语法极其简单:
ts
+  加上修饰符(默认行为,可省略)
-  去掉修饰符ts
type Foo = { a?: number; readonly b: string }
// 1. 把全部字段都变成必选(去掉 ?)
type NoOpt<T> = { [K in keyof T]-?: T[K] }
type T1 = NoOpt<Foo>      // { a: number; readonly b: string }
// 2. 把全部只读干掉(去掉 readonly)
type Writeable<T> = { -readonly [K in keyof T]: T[K] }
type T2 = Writeable<Foo>  // { a?: number; b: string }
// 3. 组合:既必选又可写
type Hard<T> = { -readonly [K in keyof T]-?: T[K] }
type T3 = Hard<Foo>       // { a: number; b: string }MyPartial 
全可选
ts
type MyPartial<T> = { [K in keyof T]?: T[K] }MyReadonly 
全只读
ts
type MyReadonly<T> = { readonly [K in keyof T]: T[K] }MyNullable 
全可空
ts
type Nullable<T> = { [K in keyof T]: T[K] | null }MyPick 
只保留某区域键
ts
type MyPick<T, K extends keyof T> = { [P in K]: T[P] }   // 内置MyOmit 
ts
type MyOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>批量加前缀 
ts
type AddPrefix<T, Pre extends string> = {
  [K in keyof T as `${Pre}${string & K}`]: T[K]
}
type Foo = { a: number; b: string }
type Prefixed = AddPrefix<Foo, '_$'>   // { _$a: number; _$b: string }