Skip to content
⚠️ This article was written in 2019. Some content may be outdated.

TypeScript ジェネリクス入門と実践

TypeScriptジェネリクスに関する記事はネット上に多くありますが、実践的な経験を持つものは少ないです。本記事では実際のプロジェクトをベースにベストプラクティスを探ります。

クイックスタート

実際の例を見てみましょう:

javascript
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].[contenthash:8].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: "babel-loader",
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
        },
      },
    },
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin({ filename: "[name].css" }),
  ],
};

このパターンをチームに展開した後、効果は非常に良く、メンテナンスコストが明らかに下がりました。

高度な使い方

以下の方法で実装できます:

javascript
const { sum, debounce } = require('./utils')

describe('utils', () => {
  test('sumの計算が正しい', () => {
    expect(sum(1, 2)).toBe(3)
    expect(sum(-1, 1)).toBe(0)
  })

  test('debounceが実行を遅延させる', () => {
    jest.useFakeTimers()
    const fn = jest.fn()
    const debounced = debounce(fn, 300)

    debounced()
    debounced()
    debounced()
    expect(fn).not.toHaveBeenCalled()

ジェネリクスを使うことで再利用可能な型安全なコードを書けます。核心的な考え方は型もパラメータであるということです——関数が値のパラメータを受け取るように、ジェネリック関数やインターフェースは型パラメータを受け取ります。

MIT Licensed