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

React泛型Hook中TypeScript转换对象为SelectOption时类型错误求助

解决TypeScript中T[string]无法赋值给string | number的类型错误

错误原因

你编写的useOptions Hook中,泛型T仅被约束为object,但T的属性类型可以是任意类型(比如boolean、复杂对象等)。而SelectOption要求label和value必须是string | number,TypeScript无法确保item[labelKey]或item[valueKey]的类型符合要求,因此抛出类型不匹配的错误。

解决方案

以下两种方案可解决该问题,根据你的业务场景选择:


方案1:通过泛型约束严格限制属性类型

直接在泛型定义中约束T的labelKey和valueKey对应的属性必须是string | number,从源头避免类型不匹配:

export interface SelectOption {
  value: number | string;
  label: number | string;
}

const useOptions = <
  T extends Record<L, string | number> & Record<V, string | number>,
  L extends keyof T,
  V extends keyof T
>(props: { items: T[]; labelKey: L; valueKey: V }) => {
  const { items, labelKey, valueKey } = props;

  const options = useMemo<SelectOption[]>(() => {
    return items.map((item) => ({
      label: item[labelKey],
      value: item[valueKey],
    }));
  }, [items, labelKey, valueKey]); // 补充labelKey和valueKey作为依赖项

  return options;
};

export default useOptions;

优点:在调用Hook时就会校验传入的items是否符合类型要求,提前暴露错误,避免运行时问题。


方案2:强制转换属性类型为string/number

如果无法约束T的属性类型,或者需要兼容其他类型的属性,可以在映射时将属性值转换为string或number:

export interface SelectOption {
  value: number | string;
  label: number | string;
}

interface IProps<T> {
  items: T[];
  labelKey: keyof T;
  valueKey: keyof T;
}

const useOptions = <T extends object>(props: IProps<T>) => {
  const { items, labelKey, valueKey } = props;

  const options = useMemo<SelectOption[]>(() => {
    return items.map((item) => ({
      // 使用String()转换为字符串,也可根据需求用Number()转换为数字
      label: String(item[labelKey]),
      value: String(item[valueKey]),
    }));
  }, [items, labelKey, valueKey]);

  return options;
};

export default useOptions;

注意:转换时要确保属性值可以被正常转换为目标类型(比如boolean转string会得到"true"/"false",符合要求;但复杂对象转string会得到"[object Object]",需要根据业务判断是否接受)。


额外修复:补充useMemo依赖项

你原来的代码中useMemo的依赖项缺少labelKey和valueKey,当这两个参数变化时,options不会重新计算,这会导致Bug,上述两个方案都已补充了完整的依赖项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:15:31