Skip to content

Add P.object and P.object.empty#233

Closed
gitsunmin wants to merge 4 commits into
gvergnaud:mainfrom
gitsunmin:main
Closed

Add P.object and P.object.empty#233
gitsunmin wants to merge 4 commits into
gvergnaud:mainfrom
gitsunmin:main

Conversation

@gitsunmin
Copy link
Copy Markdown

@gitsunmin gitsunmin commented Mar 23, 2024

Add P.object and P.object.empty

Add a pattern to match all 'Object' and 'Empty Object'.

P.object

const fn = (input: object) =>
  match(input)
    .with(P.object, () => 'Object!')
    .otherwise(() => '???');

console.log(fn({ str: 'hello' })); // Object!

P.object.empty

const fn = (input: string) =>
  match(input)
    .with(P.object.empty(), () => 'Empty!')
    .otherwise(() => 'Full!');

console.log(fn({})); // Empty!

Issue number: #230

@gitsunmin gitsunmin changed the title Add P.object and P.object.empty #230 Add P.object and P.object.empty Mar 23, 2024
Copy link
Copy Markdown
Owner

@gvergnaud gvergnaud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contributing! I have a few comments but that's a good start :)

Comment thread src/patterns.ts Outdated
pattern: pattern
): ObjectChainable<pattern> =>
Object.assign(chainable(pattern), {
empty: () => objectChainable(intersection(pattern, emptyObject())),
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like chainable would be enough here, since you can't chain empty several times

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll change it to "chainable." If it's wrong, please "comment."

Comment thread src/patterns.ts Outdated
Comment thread src/types/Pattern.ts Outdated
| 'or'
| 'and'
| 'array'
| 'object'
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure a new pattern type is necessary here because both patterns you added are implemented with guards

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll erase "object".

Comment thread src/types/Pattern.ts
GuardP<unknown, null | undefined>,
never
>;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove this diff?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I'll remove this diff

Comment thread src/types/Pattern.ts Outdated
* match(value)
* .with(P.object.empty(), () => 'empty object')
*/
empty<input>(): ObjectChainable<
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should just be Chainable here as well

Comment thread tests/object.test.ts
type t = Expect<Equal<typeof obj, { str: 'world' }>>;
return obj.str;
})
.with(P.object, (obj) => {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add test covering how P.object behaves with more inputs:

  • Functions
  • Primitive values
  • Null

It should catch all values that are assignable to the object type, and type narrowing and exhaustive should both work

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added test. If you need more, please comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, functions and arrays are part of the object type in TypeScript: Playground

I think P.object should catch anything assignable to object to stay close to typescript semantics and play nicely with exhaustiveness checking.

I'm going to update your PR shortly

- Comment: Seems like chainable would be enough here, since you can't chain empty several times
- Comment: I think we could make this more efficient by using a for in loop instead of Object.keys and breaking the loop by returning false if an object own property is encountered.
- Comment: It should just be Chainable here as well
- Comment: I'm not sure a new pattern type is necessary here because both patterns you added are implemented with guards
- Comment: Could you add test covering how P.object behaves with more inputs: Functions, Primitive values, Null. It should catch all values that are assignable to the object type, and type narrowing and exhaustive should both work
- Comment: Could you remove this diff?
@gvergnaud
Copy link
Copy Markdown
Owner

I wanted to make a few changes and realized I can't push to your repository so I had to create a new branch that includes your changes. Closing this PR in favor of #234

@gvergnaud gvergnaud closed this Mar 31, 2024
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

Successfully merging this pull request may close these issues.

2 participants