Microsoft/TypeScript

The order of values ​​in a union affects the correct type inference

Open

#59,729 创建于 2024年8月23日

在 GitHub 查看
 (2 评论) (0 反应) (0 负责人)TypeScript (6,726 fork)batch import
Domain: check: Type InferenceHelp WantedPossible ImprovementUnion Order Dependence

仓库指标

Star
 (48,455 star)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 9 个 PR)

描述

🔎 Search Terms

union order type infer

🕗 Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about union / order

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.4#code/C4TwDgpgBAshDO8CGBzaBeKBvKB7MwAlrgHbwD8AXFAEoQDGuATgCYA88wThJKANFACuJANYlcAdxIA+KAF8A3ACgloSFAASSEiwA2EJmwAqszAAoAtgmRpqRgJRR0sgG65CLZUpYNdSJtAAZsL0RKRQ8IIARvD03FEQxlAQAB7AEDrwsNaoENJmSlBFUGBIILq4SCyUhcVFAD7YUFaIuXbyUABkTQAW2noG1Fo6+oYm8rV1jTgtNhDUZo7OUEYd3Th9I4Oa-aPGsnK19tRuHl6RMXGECWZYtbNtUItOsrd4BMRk1DP+IhDA1AA5BZfv9AR05PY+LVNgMmAscPgwmR5EtZHc6pjigB6bFQAB65FqcmhkOUQA

💻 Code

type Message = { options?: Record<string, unknown> };

type Handler<T> = (message: T) => void;

declare function subscribe<T extends Message>(
    payload:
      | { message: T } & { handler: Handler<T> }
      | { message: () => T } & { handler: Handler<T> }
  ): void;

subscribe({
  message: () => ({ options: { market: 'market' } }),
  handler: ({ options }) => {
                  // ^? Record<string, unknown>
  },
});

🙁 Actual behavior

options type is Record<string, unknown>

🙂 Expected behavior

options type should be inferred as { market: string }

Additional information about the issue

if you reverse the order of values in the union:

declare function subscribe<T extends Message>(
    payload:
      | { message: () => T } & { handler: Handler<T> }
      | { message: T } & { handler: Handler<T> }
  ): void;

then the type will be inferred correctly

贡献者指南