如何以严格模式无关的方式检查对象属性是否为可选属性?
如何以不依赖严格模式的方式检测对象属性是否为可选?
之前有方案用undefined extends T[K]判断对象属性是否为可选,但这个方法不可靠——它的行为会随TypeScript严格模式(尤其是strictNullChecks)的开启或关闭而变化。默认情况下严格模式是关闭的,这意味着该方法在默认环境下会失效。
示例如下:
type X = { a?: string b: number } // 严格模式开启/关闭时均为true——这部分结果符合预期 type AOptional = undefined extends X["a"] ? true : false // 严格模式开启时为false,但关闭时为true——这里出现错误判断 type BOptional = undefined extends X["b"] ? true : false
解决方案
我们可以通过判断原类型是否能赋值给移除对应属性可选标记的类型,实现严格模式无关的检测。核心是利用TypeScript映射类型的-?修饰符移除可选标记,再通过条件类型判断兼容性:
// 通用检测工具类型 type IsOptional<T, K extends keyof T> = T extends { [P in K]-?: T[P] } ? false : true; // 测试示例 type X = { a?: string b: number } // 结果为true,a是可选属性 type AIsOptional = IsOptional<X, 'a'>; // 结果为false,b是必填属性 type BIsOptional = IsOptional<X, 'b'>;
原理说明
{ [P in K]-?: T[P] }会生成一个新类型,其中指定的K属性被强制设为必填(移除?标记)。- 如果原类型
T可以兼容这个必填版本,说明原属性本来就是必填的,返回false;否则说明原属性是可选的,返回true。 - 该方法完全基于属性的可选标记判断,和
strictNullChecks的状态无关,在任何模式下都能稳定输出正确结果。
内容的提问来源于stack exchange,提问作者Gillespie
相关产品推荐
相关产品推荐

