基于泛型的TypeScript条件类型:判断对象一级属性是否含函数
解决TypeScript条件类型判断失效问题
需求说明
- 实现条件类型
GetType<S>,需遵循以下规则:- 若对象一级属性中存在
Function类型,无论深层是否有函数,返回类型"slice"; - 若对象一级属性中无
Function类型,返回类型"group",无需检查深层属性; - 返回类型只能是
"slice"或"group",禁止返回联合类型。
- 若对象一级属性中存在
现有方案问题
原条件类型在一级属性同时包含空对象和函数时会判断失效:
type GetType<S, k = keyof S> = S[k & keyof S] extends Exclude<S[k & keyof S],Function> ? "group" : "slice"
失效案例:
// ❌ 错误返回"group",预期返回"slice" const entry = { data: {}, // 空对象 upload: () => {} } // ✅ 正确返回"slice" const entry = { data: "any value", upload: () => {} }
修正方案
调整判断逻辑,改为检查是否存在至少一个一级属性为Function类型,提供两种实现方式:
方式一:遍历键判断
type GetType<S> = keyof S extends infer K ? K extends keyof S ? S[K] extends Function ? "slice" : never : never : "group";
方式二:利用Extract提取函数属性键
type GetType<S> = Extract<keyof S, { [K in keyof S]: S[K] extends Function ? K : never }[keyof S]> extends never ? "group" : "slice";
方案解释
- 方式一:通过遍历对象的所有键,只要存在任意一个键对应的属性是
Function类型,就返回"slice";遍历完所有键都未找到函数类型属性时,返回"group"。 - 方式二:先用映射类型筛选出所有属性为
Function的键,再通过Extract提取这些键;若提取结果为never(即无符合条件的键)则返回"group",否则返回"slice"。
测试验证
// ✅ 返回"slice"(存在一级函数属性) type Test1 = GetType<{ data: {}, upload: () => {} }>; // ✅ 返回"slice"(存在一级函数属性) type Test2 = GetType<{ data: string, upload: () => {} }>; // ✅ 返回"group"(一级属性无函数,深层函数不影响) type Test3 = GetType<{ data: {}, info: { nested: () => {} } }>; // ✅ 返回"group"(所有一级属性均为非函数类型) type Test4 = GetType<{ name: string, age: number }>;
内容的提问来源于stack exchange,提问作者Arnaud
相关产品推荐
相关产品推荐

