superstruct icon indicating copy to clipboard operation
superstruct copied to clipboard

Fix mask() working incorrectly with union() when an alternative object contains extra unknown props

Open dimikot opened this issue 1 year ago • 7 comments

Fixes https://github.com/ianstormtaylor/superstruct/issues/803

Basically, it's a more proper rework of my previous PR https://github.com/ianstormtaylor/superstruct/pull/629 merged several year ago. The fact is that "mask" approach applies to object structs only, so it's more proper even conceptually to put the masking logic into object() constructor rather than having it in run(). By doing so, I also fix a bug where union() did not work properly with mask(): before, instead of removing the unknown props when a union element matches, it mistakenly threw a "Expected the value to satisfy a union" error.

Test plan

npm run test

Before, the added test threw:

CleanShot 2023-11-28 at 18 39 03@2x

After, all the tests (including the new ones) pass.

dimikot avatar Nov 29 '23 02:11 dimikot

@ianstormtaylor could you please take a look? This is a pretty straighforward change.

dimikot avatar Nov 30 '23 18:11 dimikot

@ianstormtaylor :pray:

dimikot avatar Dec 04 '23 15:12 dimikot

@ianstormtaylor 🙏🙏

dimikot avatar Dec 12 '23 04:12 dimikot

Hey @dimikot — I have recently spoken to Ian and I will be helping out with the maintenance of Superstruct from now on.

Getting union to work with mask has actually been on the top of my priority list (it's so useful and a real bummer that it currently doesn't work!) so I am psyched that you've already taken a crack at it! ✌️

I will look into your PR closely next week and get back to you.

arturmuller avatar Dec 16 '23 19:12 arturmuller

Ok, looked through your PR: One thing I am not sure about is whether it a problem that the output of mask with opaque object has changed if an array is passed as value.

// Before
mask([0, 1, 2], object()) // Returns { '0': 0, '1': 1, '2': 2 }

// Your PR
mask([0, 1, 2], object()) // Returns [ 0, 1, 2 ]

Admittedly, it doesn't feel like a very common use-case, and I actually think the new behaviour is more correct, but I would hate to have some patch-version-bump breakages for people in my first couple of releases.

arturmuller avatar Dec 16 '23 20:12 arturmuller

I think I broke it in the old PR https://github.com/ianstormtaylor/superstruct/pull/629 actually (this is likely where { '0': 0, '1': 1, '2': 2 } behavior was introduced first), so in the current PR, it's returning back to the roots. But I hear you, I'll try to figure out, how to keep the current behavior, even though it's a little unexpected.

dimikot avatar Jan 14 '24 23:01 dimikot

Hi @dimikot — please lmk if you would like to finish this PR. 🙏

arturmuller avatar Mar 11 '24 13:03 arturmuller

@dimikot — thank you for your work on this. I've merged it into main in a separate PR as I wasn't able to make changes in your branch, but your commit (and most importantly the fix itself) have made it into 2.0! Thank you so much 🙌

arturmuller avatar Jul 06 '24 10:07 arturmuller