-
Notifications
You must be signed in to change notification settings - Fork 393
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
Export additionalProperties as intersection for complex types #383
Conversation
test/__snapshots__/test/test.ts.md
Outdated
@@ -5682,6 +5691,142 @@ Generated by [AVA](https://avajs.dev). | |||
}␊ | |||
` | |||
|
|||
## realWorld.jsonschema.js |
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.
I have no idea, why this section is moved
But it doesn't seem to actually fix the problem? Or am I doing something wrong? The generated type is indeed valid TypeScript in the sense that it does compile. But if you try to create an object with it, it will still fail: export type AdditionalProperties = {
foo?: string;
} & {
[k: string]: number;
};
const bar: AdditionalProperties = {
foo: 'baz'
}
/*
Type '{ foo: string; }' is not assignable to type 'AdditionalProperties'.
Type '{ foo: string; }' is not assignable to type '{ [k: string]: number; }'.
Property 'foo' is incompatible with index signature.
Type 'string' is not assignable to type 'number'.
*/ |
It is impossible to create such an object in TypeScript, but you can use it after a cast or assertion. export type AdditionalProperties = {
foo?: string;
} & {
[k: string]: number | undefined;
};
const bar = {
foo: 'bar',
baz: 42
} as unknown as AdditionalProperties;
const foo = bar.foo; // type: string | undefined
const baz = bar.baz; // type: number | undefined
const tmp = bar.tmp; // type: number | undefined |
This is especially of interest, when a received JSON object – such as an HTTP request body – is parsed. |
We need this in our code base – any chance of a merge? |
+1 - TS serverless files are a huge win for teams building serverless apps in TS and this PR would allow that to happen |
+1 |
2 similar comments
+1 |
+1 |
Any news? We could really use this in our production code. |
# Conflicts: # test/__snapshots__/test/test.ts.md # test/__snapshots__/test/test.ts.snap
I would greatly appreciate this fix as I'm currently blocked by serverless/typescript#27. |
@bcherny – this PR would close multiple tickets. Would it be possible to initiate a review? |
@fabrykowski (and potential reviewers) please keep in mind my comment here: #356 (comment) This change will be breaking as it prevents you from using declaration merging (which can only be done with A better solution would be to generate a e.g.
|
@G-Rath – in the example you gave only the finished type I would argue that declaration merging is a very useful tool for DefinitelyTyped, allowing for example to define specific headers; should not the aim of this package be the opposite? If I have a JSON-schema and I validate a JSON-object (e.g. via ajv) then I can safely cast the object to (or assert it to be) the generated TypeScript-type! (This is, at least, the way I use this package.) If there is strong demand for it, I could add another optional compile option ( |
Sure in a perfect world it'd be great to less stuff while still being able to have the flexibility but this is what the language requires us to do in order for this change to not be breaking + retain that flexibility.
While neither are terrible alternatives, they are not without costs: casting can introduce bugs if not understood and maintained properly because the whole point of them is to have TypeScript ignore type violations like missing properties and type mismatches, and assertions can have a significant runtime cost depending on the size of the objects (which people may shortcut with approximation assertions, which is fine but then you're in the first tradeoff again).
Why is this being re-written as a I'm definitely happier if it doesn't change interfaces with no Please keep in mind that not everyone is validating their objects against the actual schemas at runtime - for example, over at https://github.com/octokit/webhooks we maintain schemas for all the webhook payloads which are used to generate the types that consumed by related packages; while the schemas are valid and can be used, they are not by the related octokit packages that are using the types. This is also the case for the rest of the GitHub API. Declaration merging is very powerful here for the same reason its powerful over at DT: if we've made a mistake, or there's some new feature, and no one's gotten around to updating the schemas & types (we're pretty responsive but stuff happens), then people can easily amend the types using DM. |
Bumping this PR because it appears that TS declaration files are straight up broken (still). I applied this fix to my local node_modules, but like... come on. How about less pedantic discussion about types and more fixy fixy? EDIT: I now realize this isn't a serverless-namespaced package. I retract my snark, but getting this merged would still be helpful to me! |
Would also love to have this merged! |
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.
Sorry for the delay.
This should be implemented as a normalizer rule, and not as a special case in the parser. The rule should be: If a schema specifies non-boolean additionalProperties
, then rewrite the schema as an allOf
of the schema (without additionalProperties
) and the additionalProperties
. That would simplify the implementation, and address @G-Rath's point about backwards-compatibility for people taking advantage of declaration merging.
* This interface was referenced by \`Callback\`'s JSON-Schema definition␊ | ||
* via the \`patternProperty\` "^x-".␊ | ||
*/␊ | ||
[k: string]: unknown;␊ |
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.
Can we improve this output?
Can we get it merged, please? The issue has been open for 2 years and is still relevant and causes problems. |
Pretty please? |
Closing out stale PRs. |
A quick fix for #299, #356 and #402.
Given the schema
it is rendered by the library as
which results in the compiler error
This PR renders the schema above as
which is valid TypeScript.