Экспресс и Typescript - свойства Error.stack и Error.status не существуют
Я пытаюсь преобразовать существующий проект node.js из javascript в typescript. Я использовал ловушку ошибок 404 по умолчанию из шаблона Visual Studio Express 4:
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
Однако я получаю следующее сообщение об ошибке:
Свойство "status" не существует в типе "Ошибка".
Я получаю подобное сообщение, если попытаюсь вызвать свойство Error.stack:
Свойство 'stack' не существует в типе 'Error'.
Кто-нибудь знает, что здесь происходит?
Изменить: Стив Фентон указывает, что я могу просто поместить статус ошибки в объект ответа. Однако мой механизм обработки ошибок использует двухэтапный процесс:
- Создайте ошибку 404 и установите ее статус
-
Передайте его следующему родовому обработчику:
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
Таким образом, состояние ошибки сначала устанавливается на объект Error, а затем возвращается обработчиком ошибок, чтобы решить, как обрабатывать ошибку.
Ответы
Ответ 1
Вы можете сказать TypeScript, что для вашего случая использования Error
может быть status
на нем:
interface Error{
status?: number;
}
Итак, вы получаете:
interface Error{
status?: number;
}
var err = new Error('Not Found');
err.status = 404;
Однако я должен сказать, что ваш экспресс-код не идиоматичен, но TypeScript может его понять, если вы расскажете об этом.
Ответ 2
Вы положили код ошибки в ответ...
app.use(function (req, res, next) {
var err = new Error('Not Found');
res.status(404)
next(err);
});
Ответ 3
Лучший способ, по моему мнению, состоит в том, чтобы отключить проверки типов, установив ошибку на any
или создав новый тип Error
, поскольку он уже существует в @types/node
.
Вместо этого вы должны расширить этот тип ошибки:
interface ResponseError extends Error {
status?: number;
}
Ответ 4
import * as express from 'express';
interface Error {
status?: number;
message?: string;
}
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
Ответ 5
Обычно это вопрос о том, как лениво инициализировать объекты в Typescript.
Идеальный способ сделать это:
interface ErrorWithStatus extends Error {
status: string
}
let foo = new Error() as ErrorWithStatus;
foo.status = '404';
Использование any
или интерфейсов с обнуляемыми полями оставляет вас со слабыми и слабыми контрактами.
Ответ 6
Другой вариант в TypeScript:
let err: any;
err = new Error();
err.status = 404;
Ответ 7
Другой вариант в TypeScript:
const err: { status?: number, message:string } = new Error('Not Found');
err.status = 404;
Ответ 8
Я просто пошел за
var err = new Error('Not Found');
err['status'] = 404;