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

TypeScriptの型定義をアップデートしたら動かなくなった話

More than 1 year has passed since last update.

事の発端

開発してるWEBアプリケーションで使ってたnpmパッケージが全体的に古くなってきたので、パッケージの更新を行った。

・・・すると、コンパイルが失敗するようになってしまい、アプリケーションが動かなくなってしまった!

問題なったコード

関連箇所のみ抜粋。

package.json
{
  "dependencies": {
    "query-string": "^6.2.0",
  },
  "devDependencies": {
    "@types/query-string": "6.1.0",
  }
}
App.tsx
import * as React from 'react';
import { parse } from 'query-string';

class App extends React.Component {
  private id: number;

  constructor(props: Readonly<{}>) {
    super(props);

    // ここから問題箇所。
    // query-stringというOSSのparseメソッドを使って
    // URLのクエリからidのパラメータが数字の文字列なら、変数idを代入する事をしたい
    const parsedHash = parse(location.search);
    // @types/query-string のバージョンが6.1.1だと、この下の行でコンパイルエラーになる
    if (isFinite(parsedHash.id)) { 
      this.id = Number(parsedHash.id);
    }
  }

  render() {
    // 略
  }
}

起こった出来事について

原因は「@types/query-string」のバージョンアップでした。

※「@types/」から始まる名前のパッケージについて知らない方はこちらをご覧ください。

6.1.0から6.1.1に更新したことによって、parseメソッドの返り値の型が変わってしまいました。

version parseの返り値の型
6.1.0 any
6.1.1 OutputParams(実態は [key: string]: string | string[] | undefined;)

返り値の型が違うので、parsedHashに結果を代入する時に型推論の結果が変わってしまい、その後の処理の型の整合性が合わなくなってしまった・・・ということでした。

↓エラーの様子
スクリーンショット 2018-11-24 10.30.38.png

その後、新しい型定義に合うようコードを修正して解決しました。

const parsedHash = parse(location.search);

if (isFinite(Number(parsedHash.id))) {
  this.id = Number(parsedHash.id);
}

まとめ

「@types/」から始まる名前のパッケージを更新するときや、自プロダクトで書いた型定義を更新する時はちゃんとコンパイルが通るかを確認しましょう(当たり前なことではありますががが)

「@types/」から始まる名前のパッケージを更新する時に、どんな事が起こる可能性があるのかが想像できてなかったのでいい勉強になりました。

今回の例は「@types/query-string」でしたが、他のパッケージでも起こる可能性はあるので、気をつけましょう。

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