rest.js: Cannot access `content` property on result of octokit.repos.getContent()
The Typescript types for octokit.repos.getContent seem to be broken.
Previously it would return a Promise<OctokitResponse<ReposGetContentResponseData>> which had a data property with a content property.
Now i get TypeScript errors trying to get to content - either through .data or directly.
'content' does not exist on type '{ type: string; size: number; name: string; path: string; content?: string; sha: string; url: string; git_url: string; html_url: string; download_url: string; _links: { git: string; html: string; self: string; }; }[] | { ...; } | { ...; } | { ...; }'.
Property 'content' does not exist on type '{ type: string; size: number; name: string; path: string; content?: string; sha: string; url: string; git_url: string; html_url: string; download_url: string; _links: { git: string; html: string; self: string; }; }[]'.
_Originally posted by @AndrewCsontos in https://github.com/octokit/octokit.js/issues/1951#issuecomment-744449274_
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 40 (33 by maintainers)
This is still happening to me. Here is what I did:
then I have my content. Hope that helps
@AndrewCsontos a workaround for now, is to add
as components["schemas"]["content-file"]wherecomponentsis imported from@octokit/openapi-types, whenever you want to access thecontentproperty.Ex:
I have just created a PR within GitHub to fix the OpenAPI spec issue.
I used this snippet of code to test.
Everything seems to work as expected now.
Great research @oscard0m!
Note that in case of a directory response, the items can be one of the four possible types:
file,dir,symlink,submodule, not justdirBlocked by: https://github.com/github/rest-api-description/issues/165
@oscard0m that sounds about what I’d expect - it’s the same reason I restructured our schemas to be per-action.
As you’ve found in the handbook, you need to have a discriminating property to be able to properly type narrow, which your proposal adds 😃
Yes, we should open an issue there, and reference back to this one.
Hey @wolfy1339 sorry for the delay here. After checking a bit deeper the issue and reading some StackOverflow / Github issues open and googling a bit, I think the following solution would be the right one, let me know what do you think:
What TypeScript handbook says: we need a to have a single field which uses literal types which you can use to let TypeScript narrow down the possible current type
Checking the different types for
contentI think thetypefield is the one we should be using:https://github.com/octokit/openapi-types.ts/blob/main/generated/types.ts#L25896-L25962
so, instead of:
we should use:
Which is already like this checking the examples in GitHub docs https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#get-repository-content but checking their OpenAPI it is not like this: https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json
If you think this is the issue… Does this mean we (I can do it myself if you want) need to open an issue in Github’s OpenAPI (I’m still not familiar with the flow and pieces)? @gr2m @wolfy1339
P.S.: Tagging @G-Rath just in case you are interested in following up or adding your thoughts on this.
Did you get any answers on your StackOverflow post?
That won’t really help much. The types are only common properties, so we’d have to add that property to all the different openapi types.
This just seems like a problem that can’t really be fixed.
I don’t find an easy solution for the problem. Searching on the Internet I found some implementations of
OneOforExclusiveUnionlike this but looks super complex to me:What about wrapping common properties in a
typeand extending it withtype { [key:string]: any}for the moment to unblock users and we ping TypeScript team? With more time we can research on existing issues for this OneOf implementation and what’s the best approach here.Tomorrow I will take a look into it and see if I can help 😉
I’ve been looking around the types and there’s 2 problems here:
response.datacan be anArraywhen the path is a directoryresponse.datadon’t include thecontentproperty (when path is a git submodule or a symlink).The first problem shouldn’t be too much of a hassle to deal with, you can easily filter it out using
Array.isArray(). The second problem is where the problem really lies, since in TypeScript you cannot access properties that aren’t common to all the different types