TypeScript条件类型:如何匹配特定可空类型
看起来你正在尝试构建一个条件类型,把Unwrapped、UnwrappedArray以及它们的可空变体转换成对应的Wrapped类型对吧?我来帮你补全并优化这个类型定义,让它能正确处理可空的情况。
首先,先把你现有的接口和未完成的类型整理完整,给出可运行的实现:
interface Unwrapped { dummyProp: string; } interface UnwrappedArray<T extends Unwrapped> extends Array<T> { } interface Wrapped<T extends Unwrapped> { unwrapped: T; } type ToPropertyWrapped<T, K extends keyof T> = // 第一步:匹配UnwrappedArray,转换为Wrapped元素的数组 T[K] extends UnwrappedArray<infer ArrayElementType> ? Wrapped<ArrayElementType>[] // 第二步:处理可空的Unwrapped联合类型(比如Unwrapped | null | undefined) : T[K] extends (infer U) | null | undefined ? U extends Unwrapped ? Wrapped<U> | Exclude<T[K], U> // 保留原有的可空性 : NonNullable<T[K]> // 非Unwrapped类型,返回非空版本 // 第三步:匹配非空的Unwrapped : T[K] extends Unwrapped ? Wrapped<T[K]> : NonNullable<T[K]>; // 其他类型直接返回非空版本
接下来拆解一下这个类型的核心逻辑:
- 数组分支:优先匹配
UnwrappedArray,通过infer提取数组内部元素类型,再把元素转换成Wrapped类型,保持数组结构不变。 - 可空类型分支:利用TypeScript的分布式条件特性,把目标类型拆分成「非空核心类型U」和「null/undefined」两部分。如果U是
Unwrapped,就把U转换成Wrapped<U>,同时保留原类型中的null/undefined,避免丢失可空性。 - 普通Unwrapped分支:如果是非空的纯
Unwrapped类型,直接转换成对应的Wrapped包装类型。 - 兜底分支:对于既不是
Unwrapped也不是其变体的类型,返回它的非空版本(你也可以根据需求调整为直接返回原类型)。
我们用几个测试用例验证效果:
// 非空Unwrapped → Wrapped<Unwrapped> type Test1 = ToPropertyWrapped<{ prop: Unwrapped }, "prop">; // Unwrapped | null → Wrapped<Unwrapped> | null(保留原null) type Test2 = ToPropertyWrapped<{ prop: Unwrapped | null }, "prop">; // UnwrappedArray → Wrapped元素组成的数组 type Test3 = ToPropertyWrapped<{ prop: UnwrappedArray<Unwrapped> }, "prop">; // 非Unwrapped的可空类型 → 保留原类型结构 type Test4 = ToPropertyWrapped<{ prop: string | undefined }, "prop">; // Unwrapped | undefined → Wrapped<Unwrapped> | undefined(保留原undefined) type Test5 = ToPropertyWrapped<{ prop: Unwrapped | undefined }, "prop">;
如果你原本考虑用NonNullable<T[K]> extends Unwrapped来处理可空情况,那会存在一个问题:它会直接把可空类型转换成非空的Wrapped,丢失了原有的null/undefined特性。而上面的写法通过拆分联合类型并保留可空成员,完美解决了这个问题。
内容的提问来源于stack exchange,提问作者David Sherret
相关产品推荐
相关产品推荐

