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

TypeScript如何约束Hook返回值:避免data与error同时为undefined?

解决方案:用通用泛型类型约束「至少一个属性非undefined」

问题本质

你的自定义Hook约定data和error不能同时为undefined,但TypeScript无法自动识别这一业务约束,因此认为组件可能返回undefined,触发类型错误。之前依赖固定联合类型的方案扩展性差,无法适配后续新增属性的场景。

通用泛型工具类型实现

定义两个可复用的泛型类型,专门处理「排除对象所有属性均为undefined」的场景:

// 匹配所有属性均为undefined的对象类型
type AllUndefined<T> = { [K in keyof T]: undefined };
// 排除全undefined的情况,确保至少一个属性非undefined
type AtLeastOneDefined<T> = Exclude<T, AllUndefined<T>>;

绑定到自定义Hook

用这个工具类型约束Hook的返回值,同时保持基础结构的灵活性:

import React from 'react';

// 定义Hook的基础返回结构(所有属性可选)
type HookBaseReturn = {
  data?: string;
  error?: string;
  // 后续新增属性直接追加即可,无需修改工具类型
  // warning?: string;
};

function useMyCustomHook(): AtLeastOneDefined<HookBaseReturn> {
  // 示例逻辑:严格遵循约束,绝不返回全undefined的结果
  const [state] = React.useState<AtLeastOneDefined<HookBaseReturn>>(() => {
    return Math.random() > 0.5 
      ? { data: "请求成功的数据" } 
      : { error: "请求失败的错误信息" };
  });

  return state;
}

组件中使用(自动通过TypeScript校验)

此时TypeScript会正确识别error和data至少有一个存在,组件的分支判断不会再触发返回值类型错误:

const MyComponent: React.FC = () => {
  const { data, error } = useMyCustomHook();

  if (error) return <div>错误:{error}</div>;
  if (data) return <div>数据:{data}</div>;

  // TypeScript自动推断:此处永远不会执行,无需额外处理
};

方案优势

  • 高扩展性:后续给Hook返回值新增属性(如warning、info),仅需在HookBaseReturn中追加定义,工具类型无需改动。
  • 强类型安全:强制Hook实现必须遵循「至少一个属性非undefined」的约束,从源头规避逻辑漏洞。
  • 代码简洁:无需手动维护冗长的联合类型分支,泛型工具自动覆盖所有合法的返回情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:16