devlog

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

TypeScriptのTuple型

  • 配列のような感じだけど、別物。
  • JavaScriptなら一括に配列として扱われている
let data1: [string, number] = ['taro', 20]; // これはオッケー
let data2: [string, number] = [20, 'taro']; // これはエラー
let data3: [string, number] = ['taro', 20, 40]; // これもエラー
let data4: [string, number] = ['taro']; // これもエラー

変数data2から、Tuple型はアノテーションで定義した順番で値が入っていないとダメな型って事が分かる。 変数data3data4から、アノテーションで定義した個数より値が少なくても、多くてもダメ。

値を取得する時は、このようにインデックスを使って得る事ができる。ここは配列と一緒。

let data1: [string, number] = ['taro', 20];

let data1_1 = data1[0]
let data1_2 = data1[1]

console.log(data1_1) // 'taro'
console.log(data1_2) // 20

型推論されるから、data1[1]に対してString.prototype.split()を行うとコンパイルエラーが発生する。 data1[1]型推論: numberだから、Stringオブジェクトのメソッドは使用できない。

let data1: [string, number] = ['taro', 20];

let data1_1 = data1[0].split('a')
console.log(data1_1) // ["t", "ro"]

// これはコンパイルエラー
// プロパティ 'split'はタイプ 'number'に存在しません。
let data1_2 = data1[1].split('a')

Tuple型は、予め決まった長さかつ、配列のインデックスに対応する型が決まっている配列みたいな型って認識で良いのだろうか。 今までJavaScriptしか触ってこなかったのでTuple型っていうのが、いまいちピンと来ない。 「Union Typesの配列じゃダメなの?」と思う部分もあるのだが、きっとインデックスに対して型が紐付いている所が便利なんだろうと思う。

TypeScriptのarray型

定義する方法が2種類ある。

let array1: number[] = [1, 2, 3]; // リテラル表現
let array2: Array<number> = [1, 2, 3]; // ジェネリクス表現

気をつけたいのが、JavaScriptだと配列の中にどんな型の値でも入れる事ができたけど、TypeScriptだと違う。 アノテーション(型注釈)で指定した値しか配列に入れる事ができない。 しかも、array型を定義する為にはアノテーションが必須っぽい。 一応、any型にすればどんなもので入れる事は可能。できれば避けるべきパターン。

let array: any[] = [1, 2, 3]; // どんな型でもOK

よくあるパターンだと必要な型をUnion Typesにして複数の型を受け入れる事ができるように定義する

let array: (string | number | boolean)[] = ['hoge', 100, false];

TypeScriptのアノテーション(型注釈)

TypeScriptでは、関数の引数や戻り値にアノテーションという型注釈を付与する事ができる。 これによって、JavaScript特有の暗黙的型変換によるバグなどを防ぐ事ができる。

アノテーションは、: 型の種類というようにコロンに続いて型の種類を指定する。

const double = (num: number) => {
  return num * 2;
}

console.log(double('aaaaaa')) // Error Argument of type '"aaaaaa"' is not assignable to parameter of type 'number'.

引数にnum: numberアノテーション(型注釈)を付与する事で、関数double()が引数として受け取る事ができるのは、number型に限定する事ができる。

const double = (num: number): number => {
  return num * 2;
}

引数の後に続いて: numberと定義する事で関数の返り値に対してもアノテーション(型注釈)を定義する事ができる。

React Hooks の useState メモ

React Hooks の useState を使用する事で、関数コンポーネントでも状態の管理・更新ができるようになる。

import React, { useState } from 'react'

const App = props => {
  const [state, setState] = useState(props)
  const {count, amount} = state

  return (
    <>
      <p>Count: {count}</p>
      <input type="number" value={amount} onChange={(e)=> setState({...state, amount: parseInt(e.target.value)})}/>
      <button onClick={() => setState({...state, count: count + amount})}>Add</button>
      <button onClick={() => setState({...state, count: count - amount})}>Subtraction</button>
      <button onClick={() => setState(props)}>reset</button>
    </>
  )
}

App.defaultProps = {
  count: 0,
  amount: 0
}

export default App
  • useState() の引数として状態管理を行う値を渡す
  • useState()の返り値は、State と State を更新する為の関数が配列(setState)
  • setStateで値を更新する時は、破壊的な更新を行わない為にスプレッド構文を使用する
  • setState()は、関数を渡す事も可能
<button onClick={() => setState((oldState) => (
  {...oldState, count: count - amount}
))}>
  Subtraction
</button>

Redux Form の reduxForm() で mapStateToProps と mapDispatchToProps を渡す方法

これに結構ハマったのでメモ。
reduxForm()が返してくる関数の引数にconnect()で mapStateToProps と mapDispatchToProps を指定する。

import React, { Component } from 'react';
import { reduxForm } from 'redux-form';
import { connect } from 'react-redux';

class SampleForm extends Component {
  render = () => {
    return // 省略
  }
};

const mapStateToProps = (state) => ({
    // 省略
});

const mapDispatchToProps = (dispatch)  => ({
    // 省略
});

export default connect(mapStateToProps, mapDispatchToProps)(
  reduxForm({
    form: 'SampleForm',
  })(SampleForm)
)

注意 mapStateToProps が引数で受け取った State をそのままリターンすると、Store の state.form が二重のオブジェクトとなって動作しない。
mapStateToProps は、必要な State だけを絞り込んでリターンする事

create-react-app で作成したプロジェクトの React Component で propTypes を指定すると WebStorm で 「Unresolved variable isRequired」とエラーが表示された件

create-react-app で作成したプロジェクトの React Component で propTypes を指定すると WebStorm で 「Unresolved variable isRequired」とエラーが表示されました。(エディター上のエラー)

ググって見ると他にも「Unresolved variable string」とエラーが表示されている方もいるようです。

github.com

この issue 辿っていくと jetbrains のサポートページへのリンク(https://youtrack.jetbrains.com/issue/WEB-26418)があり、そこでは「prop-typesパッケージをpackage.jsonに追加し、依存関係をインストールすることを検討してください。」と記載されていました。

言われた通りに yarn add prop-typesを実行すると再現がなくなったってお話です。

@ 2019 devlog