devlog

フロントエンドエンジニアの技術ブログ

TypeScriptでのsetIntervalを行うと「Type 'Timer' is not assignable to type 'number'.」とエラーが出た。

TypeScript(TSX)中でsetIntervalを行うと「Type 'Timer' is not assignable to type 'number'.」とエラーが出た。

ブラウザ環境下で実行する場合は、window.setInterval()と書いて、戻り値を: numberにする事で解決する

github.com

React + TypeScript で State をもつ class コンポーネントを作成するときは、Generics の第二引数に State の型を指定する

タイトルのまま。

「React + TypeScript で State をもつ class コンポーネントを作成するときは、Generics の第二引数に State の型を指定する」

import React, {Component} from "react";

type AppState = {
  count: number
}

class App extends Component<{}, AppState> {
  constructor(props: {}) {
    super(props);
    this.state = {
      count: 0
    }
  }

  increment = () => {
    this.setState({
      count: this.state.count + 1
    })
  };

  decrement = () => {
    this.setState({
      count: this.state.count - 1
    })
  };

  render() {
    return (
      <>
        <div>Count: {this.state.count}</div>
        <button onClick={() => this.increment()}>increment</button>
        <button onClick={() => this.decrement()}>decrement</button>
      </>
    )
  }
}

export default App;

Storybookの @storybook/addon-info で props table が表示されない!!

Storybook + React(TypeScript) の環境で「@storybook/addon-info」と「react-docgen-typescript-loader」を使用して、コンポーネントが受け取るpropsの情報をドキュメントとして生成する事ができるが、特定のコンポーネントでのみ propTables が生成できない問題が発生した。

かなりハマって時間を費やしたが、ちゃっかり「react-docgen-typescript-loader」のREADMに対応方法が書いてあった。

github.com

デフォルトでコンポーネントをエクスポートするだけでなく、名前付きエクスポートもしないとドキュメントが生成されないとの事。

import React, { FC } from 'react';

type Props = {
  text: string;
};

// ここで個別にもエクスポートする必要がある
export const Hoge: FC<Props> = props => {
  const { text } = props;

  return <div>{text}</div>;
};

export default Hoge;

これで直面した問題の解決ができた。

TypeScriptで型定義済みのオブジェクトにプロパティを追加する方法

TypeScriptでは、型が定義されているオブジェクトに追加でプロパティを追加するとエラーが発生します。

type Data = {
  id: number,
  name: 'hoge'
}

const data01: Data = {
  id: 1,
  name: 'hoge',
  created_at: new Date() // Error
}

この場合は、インデックスシグネチャを使用する事で追加のプロパティを付与する事が可能です。

type Data = {
  id: number,
  name: 'hoge',
  [index: string]: any
}

const data01: Data = {
  id: 1,
  name: 'hoge',
  created_at: new Date()
}

注意 オブジェクトの同じ階層にあるプロパティの値は、型が一致している必要があります。例えば、、

type Data = {
  id: number,
  name: 'hoge',
  [index: string]: Date
}

const data01: Data = { // Error
  id: 1,
  name: 'hoge',
  created_at: new Date()
}

この場合は、インデックスシグネチャの値に対応する型としてDate型を指定しています。 しかし、Date型はプロパティのidnameの型として相応しくなくエラーが発生します。 同階層に複数の型が指定されるプロパティがある場合、インデックスシグネチャ側の型定義はUnion Typesとして指定します。

type Data = {
  id: number,
  name: 'hoge',
  [index: string]: Date | string | number
}

const data01: Data = {
  id: 1,
  name: 'hoge',
  created_at: new Date()
}

TypeScriptでオブジェクトのプロティをUnion Typesとして設定する方法

TypeScriptでオブジェクトのプロティをUnion Typesとして設定するには、アサーションを使用します。

// obj: {bar: 1 | 2 | 3, foo: boolean, baz: string}
const obj = {
  foo: false,
  bar: 1 as (1 | 2 | 3),
  baz: '2'
}

これで、obj.barは、数値の1, 2, 3 のいずれかしか受け入れる事ができない型を定義する事ができます。

WebStorm で TypeScript の型推論をマウスオーバーで表示させたい

Visual Studio Code には、 TypeScrpt を書いている時に変数などにマウスオーバをした時に型推論が表示される機能があります。 これがすごく便利なのですが、私の好きな WebStorm で同等の機能を再現したく調べた所、設定を一箇所変更する事で同様の機能を使う事ができました。

設定 > エディタ > 一般 に表示される「マウス移動でクイック・ドキュメントを表示する」にチェックを入れます。

WebStormの設定画面キャプチャ
WebStormの設定画面キャプチャ

@ 2019 devlog