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

Type inference destructure object #50684

Open
herrlegno opened this issue Sep 8, 2022 · 7 comments
Open

Type inference destructure object #50684

herrlegno opened this issue Sep 8, 2022 · 7 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@herrlegno
Copy link

herrlegno commented Sep 8, 2022

Bug Report

Typescript seems to not be able to infer correctly a rest object type.

I've found a workaround for it by nesting the value (in playground)

🔎 Search Terms

Destructuring

🕗 Version & Regression Information

Tested in 4.5.5, 4.8.2 and next (time of writing = v4.9.0-dev.20220908)

⏯ Playground Link

Playground

💻 Code

type Value = { // This properties should be always inside the dataset, to be able to render the graph
  key: string;
  color: string;
  value: number;
};

export type GraphDataSetType<
  T extends Record<string, unknown> = Record<string, never> // This represents extra data that can be used when rendering the legend for a value
> = (
(Value & T) & {
  legend: JSXElementConstructor<Value & T>
})[];

type Props<T extends Record<string, unknown> = Record<string, never>> = {
  values: GraphDataSetType<T>;
};

/* This doesn't work */
const Component = <T extends Record<string, unknown>>({values}: Props<T>) => values.map(({ legend: CustomLegend, ...props }) => <CustomLegend {...props} />)
                                                                                                                              // ^ Error

🙁 Actual behavior

Throws an error

Type 'Omit<Value & T & { legend: JSXElementConstructor<Value & T>; }, "legend">' is not assignable to type 'IntrinsicAttributes & Value & T'.
  Type 'Omit<Value & T & { legend: JSXElementConstructor<Value & T>; }, "legend">' is missing the following properties from type 'Value': key, color, value

🙂 Expected behavior

Expect to not throw an error as Omit<Value & T & { legend: ... }, "legend" }> === Value & T

@herrlegno
Copy link
Author

herrlegno commented Sep 8, 2022

Also found another bug, but I don't know if it's React types or TypeScript Inference: Playground

@andrewbranch andrewbranch added the Bug A bug in TypeScript label Sep 9, 2022
@jakebailey
Copy link
Member

jakebailey commented Sep 9, 2022

#50604 looks about the same, in that the error message is sort of the same "omitting something that I intersected in"

Type 'Omit<T & { x: X; }, "x">' is not assignable to type 'T'.
  'T' could be instantiated with an arbitrary type which could be unrelated to 'Omit<T & { x: X; }, "x">'.

That one had a workaround (and might be correct?), but it seems like there's a bug here.

@andrewbranch
Copy link
Member

#50604 is definitely working as intended. If T is instantiated with an object that also has a property x, the result of Omit<T & { x: X }, "x"> will not be assignable to T.

Likewise, the pattern in the OP here (and my reduced case) should be an error, since T can be instantiated with an object including the legend property (or foo in my reduced case), but the elaboration in the error message is nonsensical:

Type 'Omit<Value & T & { foo: unknown; }, "foo">' is missing the following properties from type 'Value': key, color, value(2322)

This makes me think that it’s an error for a completely incorrect reason.

@andrewbranch
Copy link
Member

While I think something is definitely awry here, I’m going to bump it to the backlog since it shouldn’t compile and it doesn’t.

@andrewbranch andrewbranch removed this from the TypeScript 4.9.0 milestone Sep 9, 2022
@herrlegno
Copy link
Author

Never thought of the case where T could be instanciated with the same Omitted properties, that's correct. Nevertheless in that case the error should be something like #50604, so maybe is something else. Thank you for the clarification!

Also, could you take a look to the playground linked here?

Also found another bug, but I don't know if it's React types or TypeScript Inference: Playground

Should I make another issue in this repo or should I do it at React Types? I don't know who can be responsible of it. Thank you!

@andrewbranch
Copy link
Member

@herrlegno that’s a duplicate of #241 (congrats, you found a three-digit one!)

@andrewbranch andrewbranch added this to the Backlog milestone Sep 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants