Skip to content

Conversation

@gitsunmin
Copy link

@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
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 :)

src/patterns.ts Outdated
pattern: pattern
): ObjectChainable<pattern> =>
Object.assign(chainable(pattern), {
empty: () => objectChainable(intersection(pattern, emptyObject())),
Copy link
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
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."

| 'or'
| 'and'
| 'array'
| 'object'
Copy link
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
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".

GuardP<unknown, null | undefined>,
never
>;

Copy link
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
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

* match(value)
* .with(P.object.empty(), () => 'empty object')
*/
empty<input>(): ObjectChainable<
Copy link
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

type t = Expect<Equal<typeof obj, { str: 'world' }>>;
return obj.str;
})
.with(P.object, (obj) => {
Copy link
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
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
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
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