映射类型(Mapped Types):如何移除可选修饰符?
如何在TypeScript映射类型中移除可选修饰符
当然可以移除!你遇到的问题是因为默认情况下,TypeScript的映射类型会保留原属性的所有修饰符(包括可选性?)。要解决这个问题,只需要在映射的时候使用-?修饰符来显式移除可选标志。
解决方案1:直接使用-?修饰符
修改你的映射类型,在属性名后面加上-?,就可以把可选属性转为必填:
interface Foo { one?: string; two?: string; } type Foo2 = { [P in keyof Foo]-?: number; }; // 现在Foo2的类型是 { one: number; two: number; }
这里的-?是TypeScript映射类型的特殊语法,作用就是移除属性的可选修饰符。对应的,如果想给属性强制添加可选修饰符,可以用+?(不过默认映射已经会保留原属性的可选性,所以+?一般用在需要主动添加可选性的场景)。
解决方案2:使用内置工具类型Required<T>
TypeScript还提供了内置的Required<T>工具类型,它的核心作用就是将类型T的所有可选属性转为必填属性。你可以结合映射类型来使用它:
interface Foo { one?: string; two?: string; } // 先映射类型,再转为必填 type Foo2 = Required<{ [P in keyof Foo]: number; }>; // 或者先把Foo转为必填,再映射类型(效果完全一致) type Foo2 = { [P in keyof Required<Foo>]: number; };
两种写法最终得到的Foo2类型都是{ one: number; two: number; },选择哪种都可以,看你觉得哪种更直观。
验证效果
如果你用TypeScript编译器检查的话,现在Foo2的属性都是必填的了:
// 错误:缺少属性 'one' 和 'two' const test: Foo2 = {}; // 正确 const valid: Foo2 = { one: 1, two: 2 };
内容的提问来源于stack exchange,提问作者NSjonas
相关产品推荐
相关产品推荐

