【问题标题】:TypeScript: Have return type depend on parameterTypeScript:返回类型取决于参数
【发布时间】:2021-07-18 19:11:41
【问题描述】:

我有以下 TypeScript 函数:

declare function getUserContext(
  options: UserContextOptions
): Promise<UserContext>;

declare function getTeamContext(
  options: TeamContextOptions
): Promise<TeamContext>;

type UserContextWithoutSlackTeamOptions = Omit<
  UserContextOptions,
  'slackTeamRef'
>;

async function getContext<
  T extends
    | TeamContextOptions
    | (TeamContextOptions & UserContextWithoutSlackTeamOptions)
>(
  options: Partial<UserContextWithoutSlackTeamOptions> & T
): Promise<
  T extends UserContextWithoutSlackTeamOptions
    ? TeamContext & UserContext
    : TeamContext
> {
  const teamContext = await getTeamContext(options);
  const userContext = options.user
    ? await getUserContext({
        user: options.user,
        slackTeamRef: teamContext.slackTeam,
      })
    : undefined;

  return {
    ...teamContext,
    ...userContext,
    octokit: userContext.octokit ?? teamContext.octokit,
  };
}

这里是接口:

interface UserContextOptions {
  user: {
    id: string;
    name?: string;
  };
  slackTeamRef: string;
}

interface TeamContextOptions {
  teamId: string;
}

interface TeamContext {
  slackTeam: string;
  octokit: string;
}

interface UserContext {
  user: string | null | undefined;
  slackUser: string;
  octokit: string | undefined;
}

从逻辑上讲,我认为这会起作用,但是 TypeScript 在几个地方抱怨:

在return 声明中,它说

TS2322: Type '{ octokit: string; user?: string | null | undefined; slackUser?: string | undefined; slackTeam: string; }' is not assignable to type 'TeamContext & UserContext'.  
 Type '{ octokit: string; user?: string | null | undefined; slackUser?: string | undefined; slackTeam: string; }' is not assignable to type 'UserContext'.    
 Property 'user' is optional in type '{ octokit: string; user?: string | null | undefined; slackUser?: string | undefined; slackTeam: string; }' but required in type 'UserContext'.

TS2532: Object is possibly 'undefined'.

我查看了许多其他 SO 帖子,但我遇到的解决方案都没有适用于这个特定场景。

感谢任何帮助,谢谢。

TS Playground

【问题讨论】:

  • 请考虑修改此问题中的代码以构成minimal reproducible example,将其放入像The TypeScript Playground (link to code) 这样的独立IDE 时,可以清楚地说明您面临的问题。这将使那些想要帮助您的人立即着手解决问题,而无需首先重新创建它。它将使您得到的任何答案都可以针对定义明确的用例进行测试。
  • @jcalz 道歉,刚刚编辑了它
  • 嗯,您现在似乎在这里修改了很多代码,以至于您甚至根本没有使用重载,并且您已经停止谈论呼叫站点问题。也许我明天会回来看看这个问题是否已经稳定到值得研究的程度。
  • @jcalz 对所有更改感到抱歉,我一直在进行改进并意识到我有一个逻辑错误。我保证现在一切都很好并且稳定:)

标签: typescript types overloading conditional-types


【解决方案1】:

Function Overloads 就是为此而设计的

async function getContext(options: TeamContextOptions & UserContextWithoutSlackTeamOptions): Promise<TeamContext & UserContext>;
async function getContext(options: TeamContextOptions): Promise<TeamContext>;
async function getContext(
  options: TeamContextOptions & UserContextWithoutSlackTeamOptions | TeamContextOptions & Partial<UserContextWithoutSlackTeamOptions>
) {
  // impl...
}

declare const teamOption: TeamContextOptions
declare const mixOption: TeamContextOptions & UserContextWithoutSlackTeamOptions

async () => {
  const v1 = await getContext(teamOption) // TeamContext
  const v2 = await getContext(mixOption) // TeamContext & UserContext
}

【讨论】:

    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2022-11-17
    • 1970-01-01
    • 2023-03-30
    • 2022-11-04
    相关资源
    最近更新 更多