TIL: TypeScript로 강력한 형식의 HTTP 헤더 가져오기
목표
저는 백엔드 프레임워크 개발자입니다. TypeScript로 작성되었습니다. 내가 하고 싶은 것:
http.IncomingMessage
)를 내 사용자에게 숨기기http.IncomingHttpHeaders
). 그 모든 것이 가능하다는 것이 밝혀졌습니다.
구현
http.IncomingHttpHeaders
인터페이스를 고려하십시오.interface IncomingHttpHeaders {
'accept-patch'?: string;
'accept-ranges'?: string;
'accept'?: string;
…
'warning'?: string;
'www-authenticate'?: string;
[header: string]: string | string[] | undefined;
}
헤더 이름이 하드 코딩되어 있지만 문제는 다음과 같습니다.
따라서 사용자로부터 실제 요청을 숨기기 위해
Context
라는 클래스가 있고 각 요청에 대한 처리기에게 해당 인스턴스를 나눠줍니다.export class Context {
constructor(private req: http.IncomingMessage) { }
…
getHeader(name: ?) {
return req.headers[name];
}
}
…
우리가 하고자 하는 것은
?
대신에 어떤 종류의 유형을 도입하여 하드 코딩된 http.IncomingHttpHeaders
의 헤더만 허용하도록 하는 것입니다. 이를 "알려진 키"라고 부를 것입니다.또한 사용자가 이 목록을 쉽게 확장할 수 있기를 바랍니다.
문제 1
인터페이스에 인덱스 서명이 있기 때문에 simple
type StandardHeaders = keyof http.IncomingHtppHeaders
을 사용할 수 없습니다. 이 서명은 StandardHeaders
모든 것을 수락하여 자동 완성 및 컴파일 시간 검사가 작동하지 않습니다.솔루션 - 인터페이스에서 색인 서명을 제거하십시오. TypeScript 4.1 이상에서는 키 재매핑을 허용하고 TypeScript 2.8 이상에는 조건부 유형이 있습니다. 여기서는 4.1 버전만 제공합니다.
type StandardHeaders = {
// copy every declared property from http.IncomingHttpHeaders
// but remove index signatures
[K in keyof http.IncomingHttpHeaders as string extends K
? never
: number extends K
? never
: K]: http.IncomingHttpHeaders[K];
};
그러면 색인 서명이 제거된
http.IncomingHttpHeaders
사본이 제공됩니다.‘a’ extends string
는 true
이지만 string extends ’a’
는 false
라는 사실에 근거합니다. number
도 마찬가지입니다.이제 다음을 수행할 수 있습니다.
type StandardHeader = keyof StandardHeaders;
이것이 VSCode가 생각하는 것입니다
StandardHeader
.알려진 헤더만 있는 멋진 유형 리터럴.
getHeader(name: StandardHeader)
에 연결하고 사용해 보겠습니다.자동 완성이 작동하고 거기에 잘못된 것을 입력하면 컴파일이 중단됩니다.
문제 2.
우리는 프레임워크입니다. 이 헤더 집합은 매우 좁기 때문에 사람들에게 확장할 수 있는 기능을 제공해야 합니다.
이것은 이전 것보다 해결하기가 더 쉽습니다.
Context
제네릭을 만들고 몇 가지를 추가해 보겠습니다.export class Context<TCustomHeader extends string = StandardHeader> {
constructor(private req: http.IncomingMessage) { }
…
getHeader(name: StandardHeader | TCustomHeader) {
return req.headers[name];
}
…
}
이제 사용자는 다음과 같이 작성할 수 있습니다.
const ctx = new Context<'X-Foo' | 'X-Bar'>(...);
const foo = ctx.getHeader('X-Foo');
const bar = ctx.getHeader('X-Bar');
그리고 해당 헤더를 자동 완성합니다.
또한 컴파일 시간 검사에 포함합니다.
추가 개선 사항
우리는 프레임워크이기 때문에 사용자가
Context
클래스의 인스턴스를 직접 생성하지 않고 배포합니다. 따라서 대신 클래스ContextHeaders
를 도입하고getHeader(header: StandardHeader)
를 제네릭 메서드headers< TCustomHeader extends string = StandardHeader>: ContextHeaders<StandardHeader | TCustomHeader>
로 교체해야 합니다.그것은 독자를 위한 연습으로 남겨둡니다 =).
Reference
이 문제에 관하여(TIL: TypeScript로 강력한 형식의 HTTP 헤더 가져오기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tmlr/til-get-strongly-typed-http-headers-with-typescript-3e33텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)