1

I'm using Octokit which is a GitHub client. I'm trying to read the contents of a directory and the return type of octokit.repos.getContent is a type union that has many possible values.

I'm trying to narrow the return value of getContent to only one of those options, it looks like this:

"content-directory": {
    type: string;
    size: number;
    name: string;
    path: string;
    content?: string;
    sha: string;
    url: string;
    git_url: string | null;
    html_url: string | null;
    download_url: string | null;
    _links: {
        git: string | null;
        html: string | null;
        self: string;
    };
}[]

I created a type out of it:

type DirectoryItems = components["schemas"]["content-directory"];

and now I'm trying to use it in a type guard:

const { data } = await octokit.repos.getContent({
    // ...
});

if(data instanceof DirectoryItems) {

}

but it says

'DirectoryItems' only refers to a type, but is being used as a value here.

How can I narrow the type of data to make sure that it is indeed an array of "content-directory" items?

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
  • TypeScript's type system disappears at runtime; there's no `DirectoryItems` to check. If you want runtime type checking you have to do the work yourself, as mentioned in the question this duplicates. Good luck! – jcalz Feb 16 '21 at 21:03
  • Translating the answer there here yields [this](https://tsplay.dev/1WGDKw). – jcalz Feb 16 '21 at 21:17
  • It is a bit hard to read. What should I look for in there? – Adam Arold Feb 16 '21 at 23:25
  • In where, the code? The answers to the other question talk about possible ways to approach runtime type guards. One possible approach is to write composable type guards and derive compile-time types from them (rather than the other way around, which is not possible without compiler extensions). The linked code above does this for `DirectoryItems` (or `Array`). If you compare [here](https://tsplay.dev/jwgy9m) and squint you can see how the type guards are composed in a way that mimics declaring a type like `DirectoryItem`. – jcalz Feb 17 '21 at 01:42
  • This is just too complex and unreadable to be used in production code. – Adam Arold Feb 17 '21 at 21:18
  • 1
    Okeydokey, then perhaps you want one of the many other suggestions in [this answer](https://stackoverflow.com/a/59483318/2887218) or the other answers to that question. – jcalz Feb 17 '21 at 21:21
  • Well, probably, thanks! – Adam Arold Feb 17 '21 at 22:45

0 Answers0