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

Object with any breaks .with chaining #197

Open
gabrielalmeida opened this issue Oct 3, 2023 · 2 comments
Open

Object with any breaks .with chaining #197

gabrielalmeida opened this issue Oct 3, 2023 · 2 comments

Comments

@gabrielalmeida
Copy link

Describe the bug
Codegen generates type defs that includes any as object property types.
ts-pattern .with chaining breaks when trying to match against those objects.

// Sample type generated via codegen
type Rule = {
  // Replace any with other types and it works as expected
  unit: any;
};

const sample_rule: Rule = {
  unit: "day",
};

const result = match(sample_rule)
  .with({ unit: "day" }, () => "x")
  // Type is broken when chaining second .with, comment line below and it works as expected
  .with({ unit: "hour" }, () => "y")
  .otherwise(() => "w");
TSError: ⨯ Unable to compile TypeScript:
src/index.ts:16:11 - error TS2345: Argument of type '{ unit: string; }' is not assignable to parameter of type 'PatternMatcher<never>'.
  Object literal may only specify known properties, and 'unit' does not exist in type 'Matcher<never, unknown, any, any, unknown>'.

Code Sandbox with a minimal reproduction case
https://codesandbox.io/p/sandbox/misty-bird-wsckjn

Versions

  • TypeScript version: 5.2.2
  • ts-pattern version: 5.0.5
  • environment: node v16.17.0
@gabrielalmeida gabrielalmeida changed the title Object with any breaks .with chaining Object with any breaks .with chaining Oct 3, 2023
@gabrielalmeida
Copy link
Author

v4.1.2 introduced "Make subsequent .with clause inherit narrowing from previous clauses" which seems to be the cause of this behavior. Reverting to a version prior than that works as expected.

@gvergnaud
Copy link
Owner

gvergnaud commented Oct 7, 2023

That's unfortunately coming from this weird TypeScript behavior:

type X = Exclude<{ unit: any }, { readonly unit: 'day' }>;
  //   ^? never

I would expect X to be { unit: any } here, because { readonly unit: 'day' } is a small subset of { unit: any }...

I don't know if there is a fix for this that would be satisfactory in terms of type-checking performance (for example that wouldn't require walking through the input types to find anys and turn them into unknowns).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants