Help us understand the problem. What is going on with this article?

vscodeでObserverの型推測が正しく働かなかった現象について

More than 1 year has passed since last update.

この記事は、Business Bank Group Developers Advent Calendar 2日目の記事です。

はじめに

RxJSの5系統を使用して開発していた際に、Observableの型推測が正しく働かなかった事象を体験したので紹介しようと思います。

発生事象

const observable = Observable.of(new Task())
  .do({
    next: _.noop,
    error: console.log
  });

// エラーにならない。
observable.subscribe((val: number) => {
  console.log(`result: ${val}`);
});

上記のコードはstreamを生成する際にエラー時に共通でログに出力などそういった処理をさせたい意図で書かれたコードになっています。

上記のコードはコメントにあるように、subscribe時の引数がnumberでもエラーになりません。
observableは定義された時、 observable: Observable<any> になっているためです。

なぜ、anyになってしまうかというと、 _.noop はlodashの関数になっていますが、これの定義に原因がありました。

lodash.d.ts
noop(...args: any[]): void;

noopの定義ファイルでは上記のように定義されていたため、
observableはanyの引数を持つ、すなわちanyのstreamであるとvscodeに解釈されてsubscribe処理で自由な型指定ができてしまう現象になっていました。

回避策

いくつかあると思いますが、簡単なのは3つほど

その1
const observer = Observable.of(new Model());
observer.do({
  next: _.noop,
  error: console.log
});
その2
const observer: Observable<Model> = Observable.of(new Model())
  .do({
    next: _.noop,
    error: console.log
  });
その3
const observer = Observable.of(new Model())
  .do({
    next: () => {},
    error: console.log
  });

その1は型推測に影響を与えるdoを分離させる方針。
その2は変数に型を宣言する。
その3は型推測に影響を与えるnextの関数の引数を正す。

のいずれかの対応で回避することが可能です。

感想とRxJS 6の話

そもそも後続に影響を与えないdo関数で型推論に影響を与えているのは腑に落ちない気持ちはありますが、
これはvscodeの限界だと認めて安心できるコードを保つために置き換えていくのが大事と感じます。

また、doはRxJS 6になると廃止になりpipeで行うようになるので、型推論の問題から解放されるかと思いましたが、

const observer = of(new Model)
  .pipe<Model>(
    tap((val: string) => console.log(val)),
    map((val: number) => val.toString())
  );

上記のようなコードでもエラーにならないで通ってしまうので、RxJSでの型はなかなか難しい部分があるのかもしれません。

明日のカレンダーは @kyokoshimizu さんが担当します。よろしくお願いします。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away