2021-02-18 先日のRegroupから2日掛けてanyを撲滅した件、やはり型のテストだけでは問題を全部発見することはできておらずSentryにエラー報告が上がってきている
まずは一番多いError neverComeHere(assertion) Unhandled InitialState * onDrag
を見ていこう
これは不整合が起きた時に早めに気づけるようにとassertしてるものなのだが、開発者が気づかなかった。
うーむ、何が原因か、とブレッドクラムを遡ってみたらlassoに切り替えてるのがわかった
lassoに切り替えて試したら手元でも問題が再現した。メッセージは違って
ReferenceError: paper is not defined
とのこと。これは
const paper = require("paper");
を忘れてることによる。(え?これ型チェックで発見されないの?)
メモ
- なぜ型チェックで発見されないのか?
- lassoに切り替えて動作確認すべき(自動テストで)
そこを直すと別のエラー
TypeError: Cannot read property 'children' of undefined
これも似た問題(追記: 誤認です)
Regroupを書き始めた時、どこからでもpaperにアクセスする方法がわからなくてwindowにぶら下げてた。
const items = window.app.paper.projects[0].layers[0].children;
const paper = require("paper");
Typescipt doc: export = and import = require()をみて
import paper = require("paper");
にしたらエラー
error
SyntaxError: /Users/nishio/regroup/src/onOverlayCanvas.ts: `import =` is not supported by @babel/plugin-transform-typescript
Please consider using `import <moduleName> from '<moduleName>';` alongside Typescript's --allowSyntheticDefaultImports option.
> 2 | import paper = require("paper");
素直なimport paper from "paper";
でちゃんと動いた。なんだこれでよかったのか。
JavaScriptにモジュールの仕組みが発達する前の知識で、JavaScriptのサードパーティライブラリをJavaScript向けの解説を読みながらTypeScriptの中で使ったことで不必要にレガシーな書き方をしてしまっていた。
検索したらvar paper = require("paper");
なんてのまであった。varを使うなんて!
window.app.paper
をimport paper from "paper";
に変えていく。
おや、新しい型エラーだ
ts
Argument of type 'HTMLElement | null' is not assignable to parameter of type 'string | HTMLCanvasElement'.
Type 'null' is not assignable to type 'string | HTMLCanvasElement'. TS2345
50 | // Get a reference to the canvas object
51 | const canvas = document.getElementById("myCanvas");
> 52 | paper.setup(canvas);
なるほど、requireしたものはanyだったのか!
片付け終わったけど問題は解決してない
えーと、じっくり見てみると、これはまだ何も描画してない状態ではレイヤーが存在しないってことだから、無ければ空リストにすれば良いか
const items = paper.projects[0].layers[0]?.children ?? [];
Property 'onDeactivate' does not exist on type 'Tool'.
Property 'getBounds' does not exist on type 'PointText'.
Property 'getBounds' does not exist on type 'Layer'.