-
Notifications
You must be signed in to change notification settings - Fork 7
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
Add tests for additionalProperties #30
Conversation
I broke this out from #29 as requested here. Unfortunately, it's a little confusing right now because this PR includes the commits from #29 since the test I need to be able to pass options to ajv UPDATE: rebased/synced this PR so now it just includes the single relevant commit |
src/json-schema.ts
Outdated
@@ -108,7 +108,7 @@ type PropertiesConstraint< | |||
: unknown; | |||
|
|||
type AdditionalPropertiesConstraint< | |||
AdditionalProperties extends SchemaLike | undefined | |||
AdditionalProperties extends SchemaLike | (false | undefined) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recreating my original comment from the other PR here:
I didn't want to allow additionalProperties: true
, so I'm specifically doing (false | undefined)
instead of (boolean | undefined)
src/tsjson.test.ts
Outdated
@@ -306,6 +306,30 @@ describe("More involved tests with objects", () => { | |||
const toFail = {}; | |||
expect(() => parser.parse(JSON.stringify(toFail))).toThrow(); | |||
}); | |||
|
|||
test("Object disallowing additionalProperties", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recreating my original comment from the other PR here:
Let me know if you want me to add another test where the schema defined additionalProperties: false
, but the removeAdditional
option is omitted. I thought that might be overkill since that's more towards testing ajv's internals, which we may not need to worry about here.
I haven't checked this out and tried it yet, so I might be misunderstanding the intended use case here – but |
Oh wow, yes, I also just noticed #26! I must have tried this before that change landed, and hadn't tested it again since then. That looks like it'll work. I'll give it a shot sometime today, and close this PR if it's been solved. |
@@ -308,6 +308,175 @@ describe("More involved tests with objects", () => { | |||
}); | |||
}); | |||
|
|||
describe("additionalProperties", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ostrowr these tests are better at highlighting what I'm trying to fix. The type checking is a little off when mixing properties
with additionalProperties
. These tests that I have added fail both with and without my changes to json-schema.ts
. I.e. the issue exists in the current master
branch, and my changes to json-schema.ts
do not fix them.
It seems very difficult to get better type checking for this scenario, so I'd appreciate any pointers or suggestions you may have and I'll be happy to continue working on this.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated, but I wanted to say anyway: I found the expectType()
function quite clever! That was a nifty way to quickly and easily do typing tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I'm going to take a closer look at this PR tonight/tomorrow – appreciate the new tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know this code way better than I do, but my guess is that the fix will require combining PropertiesConstraint
and AdditionalPropertiesConstraint
the same was that AdditionalItems
is included in ItemsConstraint
Ex.
PropertiesConstraint<
Properties extends { [k: string]: SchemaLike } | undefined,
Required extends readonly (keyof Properties)[] | undefined,
AdditionalProperties extends SchemaLike | undefined // add this, and remove AdditionalPropertiesConstraint
> = // stuff
I don't know if it's possible in Typescript to define an `object like this:
type PropertiesConstraint = {
[P in keyof Properties]: Properties[P][typeof InternalTypeSymbol],
[k: /* all other properties */]: unknown
}
so for additionalProperties: S(true)
the best might be that it gives you { [k: string]: unknown }
and loses all type information for properties
. But for additionalProperties: S(false)
, it's probably possible to have it revert back to the properties
schemas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it seems like a perfect typing is blocked by microsoft/TypeScript#17867
Individual property access seems to be correctly typed, it's just the expectType<Validated<typeof schema>>(...)
checks that fail.
This may just be impossible at this point, unfortunately.
I just push some updates. It still isn't completely done (sorry for the noise), but I think this PR gets a little closer to a solution now. I'll clean up the tests sometime soon, and will push another version that actually proposes a full solution. |
Ok, I think this PR is in its final state. I don't think it's possible to do any better than is already there. I added some tests for some expected behavior. Some assertions are commented out and reference a Typescript issue that's blocking them, mostly for documentation. If you find these tests useful, we can merge this PR. Otherwise, I don't think there is any feature improvement I can make here. Thank you for all your time and attention! |
OK, this all makes sense! This type system isn't quite sound but is hopefully still useful for your use-case. I'll go ahead and merge these new tests! one thing to note is that the |
Thank you @ostrowr! Yeah, it'll be great to get a new version so I can start using the ajv properties. And I'm glad you found these tests useful. The type system is actually quite great! I think this whole project is super useful and well done. Having this simple Typescript wrapper around JSON schemas is more than enough for my use cases. I understand that not all JSON schema features will be replicable in Typescript, but you've documented all of them really well in the README. And in this particular case, it seems like we're limited by Typescript itself. I look forward to seeing what you do about the |
@bigpopakap I'm not sure if I'm going to merge this, because working on the branch it's pretty clear that I'm going to have to write some crazy types to get tests to pass typechecking, but https://github.com/ostrowr/ts-json-validator/compare/expect-true is the basic idea. Same equality relation I use in https://ostro.ws/2019/12/09/taking-types-too-far/ |
I like to be able to set
additionalProperties: false
in schemas so that Ajv'sremoveAdditional: true
option (enabled in #29) can strip out extra properties when a schema says so. (Here are the docs about theremoveAdditional
option)