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

Allow "isOfShape" to handle optional properties #36

Closed

Conversation

RebeccaStevens
Copy link
Contributor

re: #35

@RebeccaStevens RebeccaStevens changed the title WIP: "isOfShape" optional properties Allow "isOfShape" to handle optional properties Jul 9, 2020
@RebeccaStevens
Copy link
Contributor Author

One thing that needs to be considered is how should the exact vision of isOfShape work?

Maybe a better implementation of this fix would be to add a flag to determine how optional properties are handled?

@lazarljubenovic
Copy link
Owner

Hey, thanks for the PR (sorry for being late with the response). A couple of things.

I'll need to hear some convincing arguments for the added dependency. I'd like to keep the module lean. I've checked the is-plain-object implementation and it seems like there's quite a lot of extravagant details going on there. Also I'm not sure it's correct to say that an object is not “of shape” just because it has a prototype (User { name: 'John' } is of shape { name: string } as much as Object { name: 'John' } is, in my opinion).

Secondly, as I've previously written about in #8, it's not a simple decision to just drop these parameters. If code contains something like Object.keys(obj), then { a?: string }, { a: string | undefined } and { a?: string | undefined } will all produce different things.

When I see tg.isOFShape({ a: tg.isOneOf(tg.isString, tg.isUndefined }), I imagine { a: string | undefined }, not the question mark.

Maybe we should have isOptional which will work the same as isUndefined stand-alone; but when used inside of isOfShape, we could change its meaning to ?.

Something like this?

Guard Type
tg.isUndefined undefined
tg.isOptional undefined
tg.isOfShape({ a: tg.isUndefined }) { a: undefined }
tg.isOfShape({ a: tg.isOptional }) { a?: any }
tg.isOfShape({ a: tg.isOneOf(tg.isNumber, tg.isUndefined) }) { a: number | undefined }
tg.isOfShape({ a: tg.isOneOf(tg.isNumber, tg.isOptional) }) { a?: number }

Type inferring isn't gonna be an easy task, though.


As for the “exact” variant, the “exact” was added to mean “do not allow additional keys”. It should still work that way -- return false if an unknown key is found in the object (whether it's optional or not does not matter).

@RebeccaStevens
Copy link
Contributor Author

Hey, you make a great point about the prototype thing.
I did consider making an isOptional type guard and I like the idea of it but it's implementation would be the same as isUndefined. Unless something quite clever is done behind the scenes, I'm not sure if the two can act differently from isOfShape perspective.

I'll have a rethink over this and see if I can come up with a new solution.

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