TypeScript如何判断联合类型是否可能包含指定子集?
实现约束参数为包含指定类型的联合类型的
CouldContain工具 要满足你需要的参数类型约束——仅接受包含指定类型子集的联合类型,可以利用TypeScript的Extract工具类型实现CouldContain:
type One = { a: "one"; b: 1 }; type Two = { a: "two"; b: 2 }; type U = One | Two; type Z = {} | Two; // 核心类型工具:仅允许与T有非空交集的类型P type CouldContain<T, P> = Extract<P, T> extends never ? never : P; // 应用约束的函数 function test<P>(param: CouldContain<Two, P>) {}
验证案例
合法调用(通过类型检查)
const pass1: U = { a: "one", b: 1 }; test(pass1); // U是包含Two的联合类型,Extract<U, Two> = Two(非never) const pass2: Z = { }; test(pass2); // Z是包含Two的联合类型,Extract<Z, Two> = Two(非never)
非法调用(触发类型错误)
const fail1 = { a: "three", b: 3 }; test(fail1); // 类型与Two无交集,Extract结果为never,参数被约束为never const fail2 = { }; test(fail2); // 纯空对象类型与Two无交集,Extract结果为never,参数被约束为never
原理说明
Extract<P, T>会从类型P中筛选出所有可赋值给T的成员,如果P中不存在这样的成员,就返回never。- 条件类型
Extract<P, T> extends never ? never : P的作用是:仅当P与T的交集非空时,才允许P作为参数类型;否则将参数类型设为never,触发TypeScript的类型检查报错。 - 这正好匹配你的需求:只有当参数的类型本身是包含指定类型的联合类型时,才能通过检查;直接传入非联合类型或不包含指定类型的联合类型都会被拦截。
适配GraphQL动态类型场景
针对动态生成的GraphQL数据类型,只需将目标联合类型替换到Two的位置即可:
// 假设GraphQL生成的目标联合类型为GraphQLUnionType type CouldContainGraphQL<T> = Extract<T, GraphQLUnionType> extends never ? never : T; function validateGraphQLData<P>(data: CouldContainGraphQL<P>) { // 处理GraphQL数据的逻辑 }
内容的提问来源于stack exchange,提问作者Lee Benson
相关产品推荐
相关产品推荐

