You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现泛型判别式联合的Case类型?能否无需declare获取type类型?

解答你的TypeScript泛型判别式联合问题

好的,咱们来逐个解决你的两个问题:

一、无需额外declare语句获取type属性的可能取值

你完全可以直接通过索引访问联合类型的属性来获取所有type的可能值,不需要额外声明变量。这种方式更简洁直接:

interface IFoo { type: "foo"; foo: number; }
interface IBar { type: "bar"; bar: number; }
interface IBaz { type: "baz"; baz: number; }
type IObject = IFoo | IBar | IBaz;

// 直接索引IObject的type属性,得到联合类型 "foo" | "bar" | "baz"
type ObjectType = IObject["type"];

原理说明

在TypeScript中,当你对联合类型使用索引访问(比如T["key"]),编译器会自动遍历联合类型的每个成员,收集对应key的属性值,最终返回这些值的联合类型,刚好完美匹配你想要的ObjectType。

二、实现泛型Case类型及对应的filter函数

这个需求完全可行!我们可以通过条件类型实现Case泛型,再配合类型谓词让filter函数返回正确的子类型数组。

1. 定义Case泛型

// 从联合类型T中筛选出type属性等于K的成员
type Case<T, K extends string> = T extends { type: K } ? T : never;

这个条件类型的逻辑是:遍历联合类型T的每个成员,检查该成员是否包含type: K的属性,如果是则保留该类型,否则返回never(会被联合类型自动忽略)。

2. 实现类型安全的filter函数

我们可以用类型谓词(o is Case<IObject, Type>)来让TypeScript准确识别筛选后的类型:

function filter<Type extends ObjectType>(
  objects: IObject[],
  type: Type,
): Case<IObject, Type>[] {
  // 用类型谓词告诉TS:当回调返回true时,o的类型是Case<IObject, Type>
  return objects.filter((o): o is Case<IObject, Type> => o.type === type);
}

3. 使用示例

const objects: IObject[] = [
  { type: "foo", foo: 1 },
  { type: "bar", bar: 2 },
  { type: "baz", baz: 3 },
];

const fooObjects = filter(objects, "foo");
// fooObjects的类型自动推导为IFoo[],可以直接访问foo属性
console.log(fooObjects[0].foo); // 正常运行

const barObjects = filter(objects, "bar");
// barObjects的类型自动推导为IBar[]

这样你的filter函数就能根据传入的type参数,返回对应子类型的数组,完全符合预期。

内容的提问来源于stack exchange,提问作者mikea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:49:40