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

如何通过元组与重载基于函数输入设置TypeScript返回值类型?

解决方案

问题根源

你当前的实现中,中央库的useEventUtil泛型T被设为整个联合元组AllowedPairs,导致T[1]解析为MockEventPayload1 | MockEventPayload2,返回的Dispatcher接受两种payload的联合类型,自然不会对不符合单一类型的输入报错。

方案1:基于元组联合的修复

调整中央库的函数,通过泛型约束和Extract类型提取与传入事件名匹配的元组,精准推断对应的payload类型:

中央库代码:

type Dispatcher<T> = (p: T) => boolean | undefined;

export function useEventUtil<
  T extends [string, unknown],
  E extends T[0]
>(name: E): Dispatcher<Extract<T, [E, unknown]>[1]> {
  return (payload) => {
    return true;
  };
}

开发者使用代码:

import { useEventUtil } from 'central-utils'
import { AllowedPairs, MockEventTypes } from 'types-pkg'

// 显式传入AllowedPairs作为泛型参数,TypeScript会根据name自动推断对应payload
const eventUtil = useEventUtil<AllowedPairs>(MockEventTypes.MockEventType1)

eventUtil({
  name: 12 // 此时TS会报错:类型“number”的参数不能赋给类型“string”的参数
})

方案2:改用Record类型映射(更直观易维护)

将事件类型与payload的对应关系改为Record结构,类型推断逻辑会更清晰:

有效类型包代码:

enum MockEventTypes {
    MockEventType1 = 'MockEventType1',
    MockEventType2 = 'MockEventType2',
}

interface MockEventPayload1 {
    name: string;
}

interface MockEventPayload2 {
    name: number;
}

// 用Record替代元组联合,直接映射事件到对应payload
type EventPayloadMap = {
  [MockEventTypes.MockEventType1]: MockEventPayload1;
  [MockEventTypes.MockEventType2]: MockEventPayload2;
};

中央库代码:

type Dispatcher<T> = (p: T) => boolean | undefined;

export function useEventUtil<
  M extends Record<string, unknown>,
  E extends keyof M
>(name: E): Dispatcher<M[E]> {
  return (payload) => {
    return true;
  };
}

开发者使用代码:

import { useEventUtil } from 'central-utils'
import { EventPayloadMap, MockEventTypes } from 'types-pkg'

const eventUtil = useEventUtil<EventPayloadMap>(MockEventTypes.MockEventType1)

eventUtil({
  name: 12 // TS报错:类型“number”不符合MockEventPayload1的name类型string
})

两种方案都能实现你预期的类型校验,方案2的Record结构更符合TypeScript的类型映射习惯,后续扩展事件类型时也更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:46:20