如何实现满足特定属性可空规则的TypeScript泛型类型MyType
如何实现满足特定属性可空规则的TypeScript泛型类型MyType
嘿,我来帮你搞定这个TypeScript泛型的需求!先把需求再明确一遍:当传入的类型T的所有属性都是可空类型(也就是每个属性都是X | null的形式)时,MyType<T>要返回T | undefined;只要T里有至少一个属性是非空的,就直接返回T本身。
下面是具体的实现方案,我们分两步来做:
第一步:写一个辅助类型判断所有属性是否可空
首先我们需要一个辅助类型AllPropertiesNullable<T>,它的作用是检查T的每一个属性是不是都能被赋值为null:
// 辅助类型:判断T的所有属性是否都包含null作为子类型 type AllPropertiesNullable<T> = { [K in keyof T]: null extends T[K] ? true : false; }[keyof T] extends true ? true : false;
简单解释下这个辅助类型的逻辑:
- 我们先遍历
T的所有属性K,对每个属性判断null是不是它的子类型(也就是这个属性能不能取null值),得到一个由true/false组成的对象类型。 - 然后我们取这个对象所有值的联合类型,如果这个联合类型全是
true,就说明T的所有属性都可空,辅助类型返回true;否则返回false。
第二步:实现核心泛型MyType
有了辅助类型,我们就可以很轻松地写出MyType:
type MyType<T> = AllPropertiesNullable<T> extends true ? T | undefined : T;
这就是一个条件类型:如果AllPropertiesNullable<T>返回true(所有属性都可空),就返回T | undefined;否则直接返回T本身。
测试一下我们的实现
现在用你给出的例子来验证:
/* 所有属性都可空的情况 */ type A = { a: string | null, b: string | null; } type G_A = MyType<A>; // 类型结果是 A | undefined,完全符合预期 /* 至少一个属性非空的情况 */ type B = { a: string; b: string | null; } type G_B = MyType<B>; // 类型结果是 B,完全符合预期
甚至一些边界情况也能处理,比如空对象类型:
type Empty = {}; type G_Empty = MyType<Empty>; // 结果是 {} | undefined,因为空对象没有属性,我们默认认为它满足“所有属性可空”的条件
备注:内容来源于stack exchange,提问作者Evert
相关产品推荐
相关产品推荐

