Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use Pick on union with data-${string} index signature #58898

Open
DanielRosenwasser opened this issue Jun 17, 2024 · 1 comment
Open
Assignees
Labels
Domain: Big Unions The root cause is ultimately that big unions interact poorly with complex structures Needs Investigation This issue needs a team member to investigate its status.

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jun 17, 2024

Based on microsoft/fluentui#27302, and more specifically, this comment microsoft/fluentui#27302 (comment)

Playground Link

import * as React from 'react'

interface HTMLDataAttributes {
    [data: `data-${string}`]: unknown
}

interface AnchorSlots extends HTMLDataAttributes, React.AnchorHTMLAttributes<HTMLAnchorElement> {}

interface ButtonSlots extends HTMLDataAttributes, React.ButtonHTMLAttributes<HTMLButtonElement> {}

interface DivSlots extends HTMLDataAttributes, React.HTMLAttributes<HTMLDivElement> {}

const x: Pick<AnchorSlots | ButtonSlots | DivSlots, 'id'> = {id: 'id'}
//       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Expression produces a union type that is too complex to represent.

Simplified

interface Base {
  id: string;
  prop01: string;
  prop02: string;
  prop03: string;
  prop04: string;
  prop05: string;
  prop06: string;
  prop07: string;
  prop08: string;
  prop09: string;
  prop10: string;
  prop11: string;
  prop12: string;
  prop13: string;
  prop14: string;
  prop15: string;
  prop16: string;
  prop17: string;
  prop18: string;
  prop19: string;
  prop20: string;
  prop21: string;
  prop22: string;
  prop23: string;
  prop24: string;
  prop25: string;
  prop26: string;
  prop27: string;
  prop28: string;
  prop29: string;
  prop30: string;
  prop31: string;
  prop32: string;
  prop33: string;
  prop34: string;
  prop35: string;
  prop36: string;
  prop37: string;
}

interface A extends Base, HTMLDataAttributes {
  a1: string;
  a2: string;
  a3: string;
  a4: string;
  a5: string;
  a6: string;
  a7: string;
  a8: string;
}

interface B extends Base, HTMLDataAttributes {
  b1: string;
  b2: string;
  b3: string;
  b4: string;
  b5: string;
  b6: string;
  b7: string;
  b8: string;
}

interface C extends Base, HTMLDataAttributes {
  c1: string;
  c2: string;
  c3: string;
  c4: string;
  c5: string;
  c6: string;
  c7: string;
  c8: string;
}

const xyz: Pick<A | B | C, 'id'> = {id: 'id'}
//         ~~~~~~~~~~~~~~~~~~~~~
// Expression produces a union type that is too complex to represent.

The workaround I am advising is to use a different helper type: DistPick, which first distributes over each type in the union, and then applies a Pick if possible. (Playground Link):

type DistPick<T, K> =
  T extends infer _ ? (K extends keyof T ? Pick<T, K> : never) :
  never;

or even this (maybe less efficient?) version:

type DistPick<T, K> =
  T extends infer _ ? Pick<T, K & keyof T> :
  never;
@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Jun 17, 2024

And to get more similar behavior to the original Pick:

type DistPick<T, K> = Pick<
  T extends infer _ ? (K extends keyof T ? Pick<T, K> : never) : never,
  K,
>;

@DanielRosenwasser DanielRosenwasser changed the title Unable to use Pick on union with ` data-${string} ` indexer Unable to use Pick on union with data-${string}` indexer Jun 17, 2024
@DanielRosenwasser DanielRosenwasser changed the title Unable to use Pick on union with data-${string}` indexer Unable to use Pick on union with data-${string} index signature Jun 17, 2024
@DanielRosenwasser DanielRosenwasser added Domain: Big Unions The root cause is ultimately that big unions interact poorly with complex structures Needs Investigation This issue needs a team member to investigate its status. labels Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Big Unions The root cause is ultimately that big unions interact poorly with complex structures Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

2 participants