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

如何在TypeScript中为Recoil selectorFamily适配泛型、keyof及索引访问类型

问题:使用selectorFamily时无法通过泛型关联参数与返回类型

我正在使用selectorFamily访问并处理共享编辑状态中的数据,该选择器以字段名作为参数,用于访问编辑对象/atom中存在的数据。

问题在于,我无法将参数(输入)类型keyof EditTypes作为泛型来确定选择器的返回类型,目前只能定义为:

selectorFamily<EditTypes[keyof EditTypes] | null, keyof EditTypes>

TypeScript无法识别参数类型keyof EditTypes与用于确定返回的编辑对象值的键是同一个。

我尝试使用索引访问类型和keyof操作符来明确这一点,声明参数K是对应EditType结果的查找类型:

export const FieldEditSelector = selectorFamily<EditTypes[K] | null, K extends keyof EditTypes>({
    key: "fieldEditSelector",
    get:
        field =>
        ({ get }) => {
            const edit = get(WorkInProgress)
            return edit && field in edit ? edit[field] : null
        },
})

但这种定义K的方式行不通,请问是否有其他可行的方法?


解决方案

要让TypeScript正确关联参数键与返回值类型,你需要把FieldEditSelector定义为泛型函数,而非直接在selectorFamily的泛型参数中添加约束。具体实现如下:

import { selectorFamily } from 'recoil';

// 假设已有如下定义
type EditTypes = { /* 你的编辑对象类型结构 */ };
const WorkInProgress = /* 你的共享状态atom */;

export const FieldEditSelector = <K extends keyof EditTypes>() => 
  selectorFamily<EditTypes[K] | null, K>({
    key: "fieldEditSelector",
    get: (field) => ({ get }) => {
      const edit = get(WorkInProgress);
      return edit && field in edit ? edit[field] : null;
    },
  });

原理说明

  • 将FieldEditSelector声明为泛型函数后,调用时可以传入具体的键类型(如FieldEditSelector<'email'>()),TypeScript会自动推断出返回值为EditTypes['email'] | null,实现参数与返回值的类型关联。
  • 直接在selectorFamily上使用带约束的类型变量K不生效,因为selectorFamily的泛型参数需要明确的具体类型,而非带约束的类型占位符。

使用示例

// 创建针对特定字段的选择器,类型自动推断
const emailSelector = FieldEditSelector<'email'>();

// 在组件中调用
const currentEmail = useRecoilValue(emailSelector);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:15:06