typescript를 사용하여 미들웨어에서 요청 개체를 표현하는 속성을 추가하려고합니다. 그러나 객체에 추가 속성을 추가하는 방법을 알 수 없습니다. 가능하면 대괄호 표기법을 사용하지 않는 것이 좋습니다.
가능한 경우 이와 비슷한 것을 작성할 수있는 솔루션을 찾고 있습니다.
app.use((req, res, next) => {
req.property = setProperty();
next();
});
typescript를 사용하여 미들웨어에서 요청 개체를 표현하는 속성을 추가하려고합니다. 그러나 객체에 추가 속성을 추가하는 방법을 알 수 없습니다. 가능하면 대괄호 표기법을 사용하지 않는 것이 좋습니다.
가능한 경우 이와 비슷한 것을 작성할 수있는 솔루션을 찾고 있습니다.
app.use((req, res, next) => {
req.property = setProperty();
next();
});
답변:
사용자 정의 정의를 만들고 선언 병합 이라는 Typescript의 기능을 사용하려고합니다 . 이것은 일반적으로 사용됩니다 method-override.
파일 custom.d.ts을 만들고 tsconfig.json의 files섹션 에 포함해야합니다 (있는 경우). 내용은 다음과 같이 보일 수 있습니다.
declare namespace Express {
export interface Request {
tenant?: string
}
}
이렇게하면 코드의 어느 시점에서든 다음과 같은 것을 사용할 수 있습니다.
router.use((req, res, next) => {
req.tenant = 'tenant-X'
next()
})
router.get('/whichTenant', (req, res) => {
res.status(200).send('This is your tenant: '+req.tenant)
})
files섹션은 TypeScript에 포함 된 파일 세트를 제한합니다. 지정하지 않은 경우 files또는 include모든, *.d.ts기본적으로 포함되어 있으므로 사용자 정의 typings이를 추가 할 필요가 없습니다.
Property 'tenant'요청'유형에 존재하지 않습니다.`명시 적으로 포함 tsconfig.json하거나 포함하지 않아도 차이가 없습니다. UPDATE 와 declare global@basarat의 pointet 그의 answear 작품 아웃,하지만 난해야 할 일을했을 import {Request} from 'express'첫째.
Requestexpressjs에서 객체 (적어도 4.x의)
의 주석에서index.d.ts 제안한대로 Express새 멤버를 전역 네임 스페이스에 선언하기 만하면 됩니다. 예:
declare global {
namespace Express {
interface Request {
context: Context
}
}
}
import * as express from 'express';
export class Context {
constructor(public someContextVariable) {
}
log(message: string) {
console.log(this.someContextVariable, { message });
}
}
declare global {
namespace Express {
interface Request {
context: Context
}
}
}
const app = express();
app.use((req, res, next) => {
req.context = new Context(req.url);
next();
});
app.use((req, res, next) => {
req.context.log('about to return')
res.send('hello world world');
});
app.listen(3000, () => console.log('Example app listening on port 3000!'))
전역 네임 스페이스 확장 은 내 GitBook에서 자세히 다룹 니다 .
최신 버전의 Express의 경우 express-serve-static-core모듈 을 보강해야 합니다.
이제 Express 개체가 https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8fb0e959c2c7529b5fa4793a44b41b797ae671b9/types/express/index.d.ts#L19 에서 제공되므로 필요합니다.
기본적으로 다음을 사용하십시오.
declare module 'express-serve-static-core' {
interface Request {
myField?: string
}
interface Response {
myField?: string
}
}
'express'모듈을 확장하면 그렇지 않았습니다. 감사합니다!
import {Express} from "express-serve-static-core";
export {}또한 작동 하는 사용으로 전환했습니다 .
express.d.ts그렇지 않으면 컴파일러가이를 익스프레스 타이핑에 병합하려고 시도하여 오류가 발생합니다.
받아 들인 대답 (다른 사람과 마찬가지로)은 나를 위해 작동하지 않지만
declare module 'express' {
interface Request {
myProperty: string;
}
}
했다. 누군가를 도울 수 있기를 바랍니다.
*.d.ts파일 을 사용하지 않고 유형을 일반 *.ts파일에 저장 하는 경우 유용 합니다.
custom-declarations.d.tsTypeScript의 프로젝트 루트에 파일을 넣으면 저 에게도 효과적입니다.
import { Request as IRequest } from 'express/index';와 interface Request extends IRequest. 또한 typeRoot를 추가했다
8 개 정도의 답변을 시도했지만 성공하지 못했습니다. 나는 마지막으로이 작업을 얻을 관리 jd291 에의 코멘트를 가리키는 3mards가 REPO .
라는 기본 파일을 만듭니다 types/express/index.d.ts. 그리고 그것에 쓰십시오.
declare namespace Express {
interface Request {
yourProperty: <YourType>;
}
}
다음과 tsconfig.json함께 포함 :
{
"compilerOptions": {
"typeRoots": ["./types"]
}
}
그런 다음 yourProperty모든 요청에서 액세스 할 수 있어야합니다.
import express from 'express';
const app = express();
app.get('*', (req, res) => {
req.yourProperty =
});
제공된 솔루션 중 어느 것도 나를 위해 일하지 않았습니다. 요청 인터페이스를 간단히 확장했습니다.
import {Request} from 'express';
export interface RequestCustom extends Request
{
property: string;
}
그런 다음 사용하려면 :
import {NextFunction, Response} from 'express';
import {RequestCustom} from 'RequestCustom';
someMiddleware(req: RequestCustom, res: Response, next: NextFunction): void
{
req.property = '';
}
편집 : 최근 버전의 TypeScript가 이에 대해 불평합니다. 대신 다음을 수행해야했습니다.
someMiddleware(expressRequest: Request, res: Response, next: NextFunction): void
{
const req = expressRequest as RequestCustom;
req.property = '';
}
TypeScript에서 인터페이스는 개방형입니다. 즉, 재정의하기 만하면 어디서나 속성을 추가 할 수 있습니다.
이 express.d.ts 파일을 사용하고 있다는 점을 고려 하면 요청 인터페이스를 재정 의하여 추가 필드를 추가 할 수 있어야 합니다.
interface Request {
property: string;
}
그런 다음 미들웨어 함수에서 req 매개 변수 에도이 속성이 있어야합니다. 코드를 변경하지 않고 사용할 수 있어야합니다.
Request.user = {};에 app.ts어떻게 userController.ts그것에 대해 알고?
express.Handler수동으로 지정하는 대신 유형을 사용하면(req: express.Request, res: express.Response, next: express.NextFunction) => any)Request 내 속성이 존재하지 않는다고 불평하는 것과 동일하게 참조되지 않는 것 같습니다 .
declare module "express"하지만 declare namespace Express. 차라리 네임 스페이스 구문을 사용하고 싶지만 저에게는 작동하지 않습니다.
이것은 아주 오래된 질문이지만, 나는 lately.The 허용 대답은 괜찮 작동이 문제 우연히하지만 난에 사용자 정의 인터페이스를 추가 할 필요 Request- 내 코드에서 사용되었던 인터페이스와 그 허용과 함께 잘 작동하지 않았다 대답. 논리적으로 나는 이것을 시도했다.
import ITenant from "../interfaces/ITenant";
declare namespace Express {
export interface Request {
tenant?: ITenant;
}
}
그러나 Typescript는 .d.ts파일을 전역 가져 오기로 처리하고 가져 오기가 있으면 일반 모듈로 처리 되기 때문에 작동하지 않았습니다 . 이것이 위의 코드가 표준 타이프 스크립트 설정에서 작동하지 않는 이유입니다.
내가 한 일은 다음과 같습니다.
// typings/common.d.ts
declare namespace Express {
export interface Request {
tenant?: import("../interfaces/ITenant").default;
}
}
// interfaces/ITenant.ts
export interface ITenant {
...
}
.d.ts, tsconfig.json및 사용 인스턴스를? 또한 글로벌 모듈에서 가져 오기가 TS 2.9부터 만 지원되므로 어떤 버전의 typescript를 사용하고 있습니까? 그게 더 도움이 될 수 있습니다.
... "include": [ "src/**/*" ] ...나를 위해 작동하지만 "include": ["./src/", "./src/Types/*.d.ts"],그렇지 않습니다. 나는 이것을 이해하려고 아직 부서에 가지 않았다
이 문제에 대한 답변을 받았을 수도 있지만 조금만 공유하고 싶습니다. 이제는 다른 답변과 같은 인터페이스가 너무 제한적일 수 있지만 실제로 필요한 속성을 유지 한 다음 추가 할 속성을 추가 할 수 있습니다. 유형이 string값 유형 인 키any
import { Request, Response, NextFunction } from 'express'
interface IRequest extends Request {
[key: string]: any
}
app.use( (req: IRequest, res: Response, next: NextFunction) => {
req.property = setProperty();
next();
});
이제이 객체에 원하는 추가 속성을 추가 할 수도 있습니다.
express4에서 작동하는 솔루션을 찾고 있다면 다음과 같습니다.
@ types / express / index.d.ts : -------- / index.d.ts 여야합니다.
declare namespace Express { // must be namespace, and not declare module "Express" {
export interface Request {
user: any;
}
}
tsconfig.json :
{
"compilerOptions": {
"module": "commonjs",
"target": "es2016",
"typeRoots" : [
"@types", // custom merged types must be first in a list
"node_modules/@types",
]
}
}
에서 참조 https://github.com/TypeStrong/ts-node/issues/715#issuecomment-526757308
이러한 모든 응답은 어떤 식 으로든 잘못되었거나 구식 인 것 같습니다.
이것은 2020 년 5 월에 저에게 효과적이었습니다.
에서 ${PROJECT_ROOT}/@types/express/index.d.ts:
import * as express from "express"
declare global {
namespace Express {
interface Request {
my_custom_property: TheCustomType
}
}
}
에서 다음 tsconfig.json과 같이 속성을 추가 / 병합합니다.
"typeRoots": [ "@types" ]
건배.
한 가지 가능한 해결책은 "모든 대상에 이중 캐스팅"을 사용하는 것입니다.
1- 속성으로 인터페이스 정의
export interface MyRequest extends http.IncomingMessage {
myProperty: string
}
2- 이중 캐스트
app.use((req: http.IncomingMessage, res: http.ServerResponse, next: (err?: Error) => void) => {
const myReq: MyRequest = req as any as MyRequest
myReq.myProperty = setProperty()
next()
})
이중 주조의 장점은 다음과 같습니다.
-noImplicitany플래그로 벌금을 컴파일합니다.또는 빠른 (입력되지 않은) 경로가 있습니다.
req['myProperty'] = setProperty()
(자신의 속성으로 기존 정의 파일을 편집하지 마십시오. 유지 관리 할 수 없습니다. 정의가 잘못된 경우 풀 요청을 엽니 다.)
편집하다
이 경우 간단한 캐스팅이 작동합니다. req as MyRequest
MyRequest을 확장합니다 http.IncomingMessage. 그것은이 경우 아니었다 통해 더블 캐스팅 any유일한 대안이 될 것입니다
이 답변은 npm 패키지에 의존하는 사람들에게 도움이 될 것 ts-node입니다.
나는 또한 요청 객체 를 확장하는 것과 같은 문제로 어려움을 겪고 있었고 스택 오버플로에서 많은 답변을 따랐으며 아래에 언급 된 전략을 따르는 것으로 끝났습니다.
다음 디렉토리에서 express 에 대한 확장 타이핑을 선언했습니다 .${PROJECT_ROOT}/api/@types/express/index.d.ts
declare namespace Express {
interface Request {
decoded?: any;
}
}
그런 다음 tsconfig.json이와 같은 것으로 업데이트 합니다.
{
"compilerOptions": {
"typeRoots": ["api/@types", "node_modules/@types"]
...
}
}
위의 단계를 수행 한 후에도 Visual Studio는 불평을 멈추었지만 불행히도 ts-node컴파일러는 여전히 던졌습니다.
Property 'decoded' does not exist on type 'Request'.
분명히은 요청에ts-node 대한 확장 유형 정의를 찾을 수 없습니다. 개체에 .
결국 몇 시간을 보낸 후 VS 코드가 불평하지 않고 타이핑 정의를 찾을 수 있었기 때문에 ts-node컴파일러에 문제가 있음을 암시했습니다 .
업데이트 시작 script이 package.json나를 위해 수정되었습니다.
"start": "ts-node --files api/index.ts",
--files인수 여기서 중요한 역할을 사용자 정의 유형 정의를 결정 찾을 수 있습니다.
자세한 내용은 https://github.com/TypeStrong/ts-node#help-my-types-are-missing을 방문하십시오.
ExpressJS의 요청을 연장하려고 할 때 2020 년 5 월 말에 시도해 볼 다른 것을 찾고있는 사람을 돕는 것이 저에게 효과적이었습니다. 이 작업을 수행하기 전에 12 개 이상의 작업을 시도해야했습니다.
"typeRoots": [
"./node_modules/@types",
"./your-custom-types-dir"
]
declare global {
namespace Express {
interface Request {
customBasicProperty: string,
customClassProperty: import("../path/to/CustomClass").default;
}
}
}
{
"restartable": "rs",
"ignore": [".git", "node_modules/**/node_modules"],
"verbose": true,
"exec": "ts-node --files",
"watch": ["src/"],
"env": {
"NODE_ENV": "development"
},
"ext": "js,json,ts"
}
이 답변에 이미 꽤 늦었을 수도 있지만 어쨌든 여기에 내가 해결 한 방법이 있습니다.
tsconfig파일 에 유형 소스가 포함되어 있는지 확인하십시오 (완전히 새로운 스레드 일 수 있음).expressexpress디렉토리 내에서 파일을 만들고 이름을 지정합니다 index.d.ts(정확히 일치해야 함).declare module 'express' {
export interface Request {
property?: string;
}
}