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

如何用枚举实现TypeScript函数的条件返回类型以减少冗余代码?

合并帖子查询函数的简洁实现方案

先明确基础类型与枚举

首先定义核心的类型与访问级别枚举,这是实现的基础:

// 访问级别枚举(用字符串枚举更直观)
enum AccessLevel {
  Normal = 'normal',
  Protected = 'protected'
}

// 普通帖子类型(公开可见字段)
type NormalPost = {
  id: number;
  title: string;
  content: string;
  comments: string[];
};

// 保护帖子类型(继承普通字段+敏感信息)
type ProtectedPost = NormalPost & {
  sensitiveMetrics: {
    views: number;
    likes: number;
    internalNotes: string;
  };
};

两种简洁的实现方案

方案一:泛型+条件返回类型

直接利用TypeScript的条件类型,结合泛型绑定访问级别,让返回类型自动匹配传入的参数:

function getPost<T extends AccessLevel>(
  id: number,
  accessLevel: T
): T extends AccessLevel.Protected ? ProtectedPost : NormalPost {
  // 模拟数据库查询获取基础帖子数据
  const basePost: NormalPost = {
    id,
    title: '示例帖子',
    content: '帖子正文内容',
    comments: ['用户评论1', '用户评论2']
  };

  // 根据访问级别返回对应类型
  if (accessLevel === AccessLevel.Protected) {
    return {
      ...basePost,
      sensitiveMetrics: {
        views: 1200,
        likes: 68,
        internalNotes: '仅创建者可见的内部数据'
      }
    } as ProtectedPost;
  }

  return basePost as NormalPost;
}

调用时TypeScript会自动推断返回类型:

const publicPost = getPost(1, AccessLevel.Normal);
// publicPost 类型为 NormalPost,无法访问 sensitiveMetrics

const creatorPost = getPost(1, AccessLevel.Protected);
// creatorPost 类型为 ProtectedPost,可访问所有字段

方案二:函数重载(更直观)

如果不需要泛型的灵活性,函数重载的写法可读性更强,直接为不同访问级别参数指定对应返回类型:

// 重载签名:定义不同参数对应的返回类型
function getPost(id: number, accessLevel: AccessLevel.Normal): NormalPost;
function getPost(id: number, accessLevel: AccessLevel.Protected): ProtectedPost;

// 实现签名:统一处理业务逻辑
function getPost(id: number, accessLevel: AccessLevel): NormalPost | ProtectedPost {
  const basePost: NormalPost = {
    id,
    title: '示例帖子',
    content: '帖子正文内容',
    comments: ['用户评论1', '用户评论2']
  };

  if (accessLevel === AccessLevel.Protected) {
    return {
      ...basePost,
      sensitiveMetrics: {
        views: 1200,
        likes: 68,
        internalNotes: '仅创建者可见的内部数据'
      }
    };
  }

  return basePost;
}

这种方式调用时的类型推断效果和方案一完全一致,代码逻辑更直白。

关于你的构想

你提出的用枚举作为条件的思路完全正确,只需修正枚举的语法(TypeScript枚举定义不用=,而是enum AccessLevel { ... }),再结合上述两种方式,就能实现简洁的合并函数,彻底消除代码冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:57:52