ライブラリメンテナ目線でdistに対するpatchファイルを生成する

メモ。ライブラリメンテナ目線でユーザーにpatchを提示したいときがある。

たとえばある場所でログを吐いて欲しいみたいなとき。開発コード上でpatch内容を書いてそれをdistに吐いて、その差分をpatchにしたいというユースケースで、patch-packageがうまく使えないときというのはある。patch-packageでやり方がもしかするとあるのかもしれないが、わからなかった。

メモ

  1. まずgit管理下にするために既存distのファイルをstageにあげる git add -f ./packages/hoge-lib/dist/core/piyo.mjs
  2. srcファイルを書き換えて目的の処理を書く
  3. ビルドコマンドでdistを更新する
  4. git diff ./packages/hoge-lib/dist/core/piyo.mjs > piyo.patch

これでdiffが吐ける。

あとはコードブロックにこう書いたり、patchファイルを渡したりすればよい。

```diff
<ここにpatchの内容>
```

TypeScriptでオプショナルオブジェクトを埋めるときsatisfiesを使うとグッド

satisfies の使いどころをメモする。たまにしか使わないから忘れがちだけど思い出すと便利なときがたまにある。

satisfiesとは

他者のスライドだがこれがわかりやすいと思う。

使いどころ

例えばライブラリを作っていて、configの定義がありデフォルトのオプションもあって、ユーザーはオプションを上書きできるというシーンを想定する。

そうすると、configの型は厳密で、ユーザー側の型はすべてオプションオブジェクトになる。

type Config = {
  foo: number;
  bar: string;
  baz: string[];
};

type OptionalConfig = Partial<Config>;

2つ例を書く。どちらもエディタの補完は効くが、変数の結果の型が違う。前者は Partial<Config> になるが、後者はConfig型をベースに非オプショナルな中身のみになる。

const myWidenConfig: OptionalConfig = {
  bar: "baaar",
  baz: ["b", "a", "z"],
};

これはTSコンパイラではこのように解釈される。当たり前にPartialのままで、実体の変数ではfooプロパティは定義していないし型でも未定義のままになる。

satisfies を使うとこう書くことができる。

const mySatisConfig = {
  bar: "baaar",
  baz: ["b", "a", "z"],
} satisfies OptionalConfig;

これはTSコンパイラではこのように解釈される。Config型をベースに定義したものだけが入っていてundefinedではなくなっており、fooに関する情報はない。

なので、例えばオプショナルではないConfigのプロパティを期待するところにこうやって気持ちよく挿せる。

どちらもランタイムでは非undefinedだが、pleaseBar1のほうは型エラーになる。一方pleaseBar2のほうはsatisfiesを介しているので補完が効いた上で非undefinedを表現できている。

手元で理解するには

プレイグラウンドを見るのがよいと思う