LoginSignup
12
8

More than 3 years have passed since last update.

【TypeScript x Express】クエリパラメータ(req.query.~)に型をつける

Last updated at Posted at 2021-04-20

Expressのrouterで取得できるクエリパラメータにはデフォルトで
string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined
という型がつく。

import express from 'express';

const router = express.Router();

router.get('/', (req, res, next) => {
    const userId = req.query.id;
    // const userId: string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined
    const userName = req.query.name;
    // const userName: string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined
}

これを string | undefined に変更したい。

方法1 型アサーション

import express from 'express';

const router = express.Router();

router.get('/', (req, res, next) => {
    const userId = req.query.id as string | undefined;
    // const userId: string | undefined
    const userName = req.query.name as string | undefined;
    // const userName: string | undefined
}

req.query. で補完されないので微妙

方法2 Request型を継承して新しい型を作る

import express, { Request } from 'express';

const router = express.Router();

interface ExRequest extends Request {
  query: {
    id: string | undefined
    name: string | undefined
  }
}

router.get('/', (req: ExRequest, res, next) => {
    const userId = req.query.id;
    // const userId: string | undefined
    const userName = req.query.name;
    // const userName: string | undefined
}

インデックスシグネチャを使うとかっこいいかも?

import express, { Request } from 'express';

const router = express.Router();

type queryKeys = 'id' | 'name';

interface ExRequest extends Request {
  query: { 
    [key in queries]: string
  }
}

router.get('/', (req: ExRequest, res, next) => {
    const userId = req.query.id;
    // const userId: string | undefined
    const userName = req.query.name;
    // const userName: string | undefined
}

ファイル分割するともっとかっこいいかも?

routes/types/index.d.ts
import { Request } from 'express';

type queryKeys = 'id' | 'name';

export interface ExRequest extends Request {
  query: { 
    [key in queries]: string
  }
}
routes/hoge.ts
import express from 'express';
import { ExRequest } from './types'

const router = express.Router();

router.get('/', (req: ExRequest, res, next) => {
    const userId = req.query.id as string | undefined;
    // const userId: string | undefined
    const userName = req.query.name as string | undefined;
    // const userName: string | undefined
}

方法3 Request型の定義を拡張する

routes/types/index.d.ts
export declare module 'express' {
  // ↑と書くとこの{}の中は@types/express/index.d.tsの名前空間eになる

  type querykeys = 'id' | 'name' ;

  interface Request {
    query: { [key in querykeys]: string | undefined }
  }
}
routes/hoge.ts
import express from 'express';
import { Request } from 'express';

const router = express.Router();

router.get('/', (req: Request, res, next) => {
    const userId = req.query.id;
    // const userId: string | undefined
    const userName = req.query.name;
    // const userName: string | undefined
}
12
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8