Description
ππ» Advanced TypeScript for the future Octokit SDK
π
Friday, June 18, 2021
π 12:30pm Pacific Time (in your timezone)
ποΈ with @orta
π https://twitch.tv/gregorcodes
π·οΈ TypeScript, Octokit
Extending constructor options by plugins.
The Octokit SDK is built using a modular plugin architecture. The core package is @octokit/core
, which can be extended using plugins, e.g. like this
// plugin.js
module.exports = function helloWorldPlugin(octokit, options = { greeting: "Hello" }) => {
// add a custom method
return {
helloWorld: () => console.log(`${options.greeting}, world!`);
}
};
// index.js
const { Octokit } = require("@octokit/core")
const helloWorldPlugin = require("./plugin")
const MyOctokit = Octokit.plugin(helloWorldPlugin);
const octokit = new MyOctokit({ greeting: "Moin moin" });
octokit.helloWorld(); // logs "Moin moin, world!"
The important bit is that typing octokit.
will suggest both Octokit's core methods such as octokit.request
and octokit.graphql
, but also octokit.helloWorld()
.
But something that is not currently possible is to extend the types the types for Octokit's constructor options so that when I type new Octokit({
it would suggest { greeting }
as an option.
I started a pull request at gr2m/javascript-plugin-architecture-with-typescript-definitions#56 to implement it with Orta.
Inherit constructor options
Currently Octokit has no required options. But one thing we want to improve is the developer experience to build code for GitHub Enterprise Server or GitHub AE. In order to differentiate between the two we will probably add some kind of version
parameter that can be set to api.github.com
, ghes3.2
or ghes-3.1-compatible
.
The other reason that we will require constructor options inheritance will be types for the Authentication strategies (see next section).
So given that version
will be a required parameter, this code should be possible without any type errors
const OctokitGHE31 = Octokit.defaults({ version: 'ghe-3.1' })
const octokit = new OctokitGHE31()
Types for Authentication strategies
I have a long standing open issue for this one: octokit/core.js#323
Basically what I want a better developer experience when using authentication strategies such as @octokit/auth-app
import { Octokit } from "@octokit/core";
import { createAppAuth } from "@octokit/auth-app"
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
// should provide IntelliSense for createAppAuth options:
// https://github.com/octokit/auth-app.js/#createappauthoptions-or-new-octokit-auth-
}
})
This should work together with the inheritence of options types from Octokit.defaults()
so this will be possible
import { Octokit } from "@octokit/core";
import { createAppAuth } from "@octokit/auth-app"
const AppOctokit = Octokit.defaults({
authStrategy: createAppAuth
})
const octokit = new AppOctokit({
auth: {
// should provide IntelliSense for createAppAuth options:
// https://github.com/octokit/auth-app.js/#createappauthoptions-or-new-octokit-auth-
}
})
Outline
- The TypeScript for today's @octokit and where it falls short
- Make Types extendable by plugins (feat: extend
Base
constructor options with pluginsΒ javascript-plugin-architecture-with-typescript-definitions#56) - Remember default options set with
Octokit.defaults()
Preparation
- Prepare https://github.com/gr2m/javascript-plugin-architecture-with-typescript-definitions for the show:
- rewrite it JavaScript as native ES Module with separated Type definitions in
index.d.ts
- Prepare questions to work through with @orta during the show
- rewrite it JavaScript as native ES Module with separated Type definitions in
- 30 minute announcement tweet
- start of show tweet
- comment on issue
- recording available tweet
Recording
will be added after the show
Shownotes
- We used the code example show at https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-plugin-d-ts.html to make the type merging work for
Base.options
defined in plugins. - Playground for the AuthStrategy/Auth options types problem we couldn't figure out in the end: TypeScript playground
- TS Playground asking the community how to solve the issue inferring the generic type https://twitter.com/gr2m/status/1405998002674700289
- A solution proposal from the TS community: https://twitter.com/gr2m/status/1406037504164204547