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

fix: remove "empty object" type from schema #353

Merged
merged 2 commits into from
May 11, 2023
Merged

fix: remove "empty object" type from schema #353

merged 2 commits into from
May 11, 2023

Conversation

wolfy1339
Copy link
Member

@wolfy1339 wolfy1339 commented May 5, 2023

See https://github.com/octokit/plugin-rest-endpoint-methods.js/actions/runs/4896632745/jobs/8743680367?pr=632#step:5:21


Behavior

Before the change?

  • There used to be an empty object allowed in the schema, that empty object is causing issues in types downstream

After the change?

  • Removes the empty object from the schema, and it should resolve the type issues downstream

Other information


Additional info

Pull request checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Added the appropriate label for the given change

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • Yes (Please add the Type: Breaking change label)
  • No

If Yes, what's the impact:

  • N/A

Pull request type

Please add the corresponding label for change this PR introduces:

  • Bugfix: Type: Bug

@wolfy1339 wolfy1339 added the Type: Bug Something isn't working as documented label May 5, 2023
@ghost ghost added this to Bugs in JS May 5, 2023
@wolfy1339
Copy link
Member Author

This is blocking updates downstream.

@oscard0m
Copy link
Member

oscard0m commented May 11, 2023

Hey @wolfy1339,

Thanks for opening this PR and being on top of this.

I've tried to quickly catch up on the root cause of the issue. Checking the failing test, I see the inferred TS type giving problems are:

// ...
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };

type XOR<T, U> = T | U extends object
  ? (Without<T, U> & U) | (Without<U, T> & T)
  : T | U;

type OneOf<T extends any[]> = T extends [infer Only]
  ? Only
  : T extends [infer A, infer B, ...infer Rest]
  ? OneOf<[XOR<A, B>, ...Rest]>
  : never;
// ...

files?: {
   [key: string]:
       | OneOf<
           [
              {
                 /** @description The new content of the file. */
                 content?: string;
                 /** @description The new filename for the file. */
                 filename?: string | null;
              },
              Record<string, never>
            ]
         >
     | undefined;
};

The associated schema I find in api.github.com.deref.json is:

"files": {
   "description": "The gist files to be updated, renamed, or deleted. Each `key` must match the current filename\n(including extension) of the targeted gist file. For example: `hello.py`.\n\nTo delete a file, set the whole file to null. For example: `hello.py : null`.", 
  "example": { 
      "hello.rb": {
          "content": "blah",
          "filename": "goodbye.rb"
       }
   },
   "type": "object",
   "additionalProperties": {
   "type": "object",
   "nullable": true,
   "properties": {
      "content": {
         "description": "The new content of the file.",
         "type": "string"
      },
      "filename": {
         "description": "The new filename for the file.",
         "type": "string",
         "nullable": true
      }
   },
   "anyOf": [
      {
         "required": [
            "content"
         ]
      },
      {
         "required": [
            "filename"
         ]
      },
      {
         "type": "object",
         "maxProperties": 0
      }
   ]
   }
}

Should we try to fix the generated TS type instead of excluding part of the schema?

Here's a TS playground link with the issue.


A simple solution that comes to my mind is to move the Record<string never> outside of the OneOf<...>. It seems to work, but I'm not sure if we are losing some type use-cases I'm not aware.

files?: {
   [key: string]:
       | OneOf<
           [
              {
                 /** @description The new content of the file. */
                 content?: string;
                 /** @description The new filename for the file. */
                 filename?: string | null;
              },
-              Record<string, never>
            ]
         >
+    | Record<string, never>
     | undefined;
};

TS playground example with this solution proposal

@wolfy1339
Copy link
Member Author

The way the override for the schema is made, an empty object is possible already since none of the properties are set as required.

Which makes it equivalent to the original schema

@wolfy1339
Copy link
Member Author

Also see #349 for more context

@oscard0m
Copy link
Member

The way the override for the schema is made, an empty object is possible already since none of the properties are set as required.

Which makes it equivalent to the original schema

Oh! It's true! I should have double-checked that in my first TS Playground example.

@wolfy1339 wolfy1339 merged commit b5fb653 into main May 11, 2023
JS automation moved this from Bugs to Done May 11, 2023
@wolfy1339 wolfy1339 deleted the fix-override branch May 11, 2023 12:11
@octokitbot
Copy link
Collaborator

🎉 This PR is included in version 11.1.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
released Type: Bug Something isn't working as documented
Projects
Archived in project
JS
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants