如何确保TypeScript泛型联合类型包含指定类型A?
确保泛型类型T包含指定类型A的实现方案
需求:让泛型函数仅接受联合类型中包含A的参数T,不能把T限制为A|B|C这类固定联合,要保留对任意联合类型的灵活性。
原代码示例
class A { _tag = "a" as const } class B { _tag = "b" as const } class C { _tag = "c" as const } const f = <T>(value: T) => {}; // 合法:T = A|B,包含A const ab = new A() as A | B; f(ab); // 合法:T = A|B|C,包含A const abc = new B() as A | B | C ; f(abc); // 不合法:T = B|C,不包含A,但当前无报错 const bc = new C() as B | C; f(bc); // 此处需要触发TypeScript错误
之前的无效尝试
const f = <T extends A>(value: T) => {};:限制T必须是A的子类型,A|B这类联合不满足直接报错const f = <T extends A | unknown>(value: T) => {};:unknown导致约束失效,任何类型都能通过,包括B|Cconst f = <T extends A | any>(value: T) => {};:any同样让约束失效,无法过滤B|Cconst f = <T>(value: T | A) => {};:仅允许参数是T或A,但T本身可以是B|C,达不到约束T包含A的目的
正确实现方案
const f = <T extends A extends T ? unknown : never>(value: T) => {};
代码解释
这里利用TypeScript条件类型实现泛型约束:
- 当
A extends T为true(即T的联合类型包含A),约束自动转为unknown,T可以正常传递 - 当
A extends T为false(即T不包含A),约束转为never,传入的类型(比如B|C)无法赋值给never,触发TypeScript错误
验证效果
- 调用
f(ab)(T=A|B):A extends A|B为true,无报错 - 调用
f(abc)(T=A|B|C):A extends A|B|C为true,无报错 - 调用
f(bc)(T=B|C):A extends B|C为false,触发类型错误,符合预期
内容的提问来源于stack exchange,提问作者clara raquel
相关产品推荐
相关产品推荐

