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

如何复用TypeScript自定义Hook的返回类型?

问题描述

我实现了如下自定义Hook:

export const useCreateAccount: UseCreateAccountOutputs = () => {
     ...

     return { error, loading, createAccount };
};

并定义了对应的类型:

type CreateAccountFn = () => Promise<void>;
type UseCreateAccountOutputs = () => {
    loading: boolean;
    error: string | null;
    createAccount: CreateAccountFn;
};

由于要创建多个类似的自定义Hook,不想重复定义loading: boolean;和error: string | null;这两个字段,于是定义了一个基础类型用于扩展:

export type CustomGraphqlHookOutputs = () => {
    loading: boolean;
    error: string | null;
};

但尝试了两种写法都无法达到预期效果:

第一种写法:

type UseCreateAccountOutputs = CustomGraphqlHookOutputs &
    (() => {
        createAccount: CreateAccountFn;
    });

第二种写法:

type UseCreateAccountOutputs = () => {
    ...CustomGraphqlHookOutputs,
    createAccount: CreateAccountFn;
};

请问这两种写法的问题出在哪里?

错误原因

核心问题是你把CustomGraphqlHookOutputs定义成了函数类型,但实际你需要复用的是函数返回的对象结构类型:

  • 第一种写法里,交叉两个函数类型只会要求类型兼容(比如参数、返回值都要满足两个函数的要求),根本不会合并它们的返回值字段,所以完全达不到复用字段的目的。
  • 第二种写法里,你试图在对象中展开一个函数类型,这是无效操作,TypeScript无法识别这种写法,自然会报错。
正确实现方式

先把基础类型改成函数返回的对象结构,而非函数类型:

// 只定义Hook返回对象中重复的字段结构
export type CustomGraphqlHookBaseResult = {
    loading: boolean;
    error: string | null;
};

然后在定义Hook的输出类型时,让函数返回基础类型与自定义字段的组合:

type CreateAccountFn = () => Promise<void>;
// 方式1:交叉类型
type UseCreateAccountOutputs = () => CustomGraphqlHookBaseResult & {
    createAccount: CreateAccountFn;
};

// 方式2:对象扩展(与方式1效果一致)
type UseCreateAccountOutputs = () => {
    ...CustomGraphqlHookBaseResult,
    createAccount: CreateAccountFn;
};

这样修改后,所有需要loading和error字段的自定义Hook,都可以直接复用CustomGraphqlHookBaseResult类型,避免重复定义重复字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:57:43