с использованием TypeScript 3.5
, express
в 4.17
и @types/express
в 4.17
, каков правильный синтаксис для доступа к запросу параметрам? Мы начали проекты несколько лет назад, и это было довольно просто. Внутри наших обработчиков:
function getSomething(req: Request, res: Response) {
const { context, name } = req.query;
// call something with a string parameter
doSomethinWithStrings(context, name);
}
Теперь мы наконец-то обновляем некоторые версии до TS 3.x
, но с улучшенной проверкой типа TS и новыми определениями для express
мы получаем ошибки:
Argument of type 'string | Query | (string | Query)[]' is not assignable to parameter of type 'string'.
Мы попытались объявить некоторый глобальный интерфейс (например, для всех наших запросов требуется контекст). Но используя синтаксис as
, он по-прежнему жалуется:
// ~/definitions.d.ts
interface CtxQuery {
context: string;
name: string;
}
// handler.ts
...
const { context, name } = req.query as CtxQuery;
Затем он жалуется на возможные несовместимые типы:
Conversion of type 'Query' to type 'CtxQuery' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type 'Query' is missing the following properties from type 'CtxQuery': context, name
Мы можем успокоить это последнее предупреждение, используя type
вместо interface
. Но это все еще кажется большой работой для чего-то, что раньше было таким простым. Чего мне не хватает?
Да, мы можем решить все это с помощью as any
, но это не правильно. Мы используем express-validator
, поэтому мы знаем форму данных (по крайней мере, столько, сколько нам нужно / может)
обновление
В качестве быстрого обходного пути, Я создал safeQuery<T>()
generi c метод, который работает довольно гладко:
import { Request } from 'express';
export function safeQuery<T extends string>(q: Request): { [k in T]: string } {
return q.query as any;
}
При использовании с деструктуризацией объекта это без шва:
const { context, name} = safeQuery(req);
doSomethinWithStrings(context, name); // works like a charm, context and name are strings