retlat's blog

Node Native Addon を TypeScript で使うために型定義する

Node から OS の C API を触りたくて Native Addon を生成していて、使う側はいつも通り TypeScript でやりたい
ディレクトリ構成はこんな感じ

.
|- src
|  |- index.ts
|  `- sample.node
|- package.json
|- tsconfig.json
`- yarn.lock

Addon は sample 関数だけ export しているとして、 index.ts はこんな感じで import する

import { sample } from './sample.node'

sample()

そうするとモジュール名の箇所で
error TS2307: Cannot find module './sample.node' or its corresponding type declarations.
となる

Vue.js の SFC を TypeScript で使う時と同じエラーの出方だなーと思ったので、

declare module "*.node" {
  export function sample(): string;
}

という型定義ファイルを index.ts の隣に置く
これでエラーが消えて、ちゃんと補完が効いたり解析が正しく動くようになる
ただこれだと複数の addon がある時には同じ型定義になってしまう

これは Wildcard module declarations という JS 以外のファイルを扱うケース向けの機能を使っている
今回の場合は suffix で判定しているため、以下のようにすると複数の addon に違う型が適用される

// import {} from './sample.node' の時に使われる
declare module "*sample.node" {
  export function sample(): string;
}

// import {} from './foobar.node' の時に使われる
declare module "*foobar.node" {
  export function foobar(): string;
}

解決方法として妥当かはよくわからないけど、まあなんとかなる
Monorepo なら多少楽になるかもしれないけど、どちらにせよ自分で書くのは面倒なので C++ の実装から型定義を自動生成したいなー