728x90
SMALL
※ 인프런 - Node.js에 TypeScript 적용하기(feat. NodeBire) by 조현영 강의를 기반으로 정리한 내용입니다.
오버로딩? 같은 매개변수를 여러 방법으로 설정하는 것
이전 글에서 local.ts 파일에 해당하는 타입 정의를 위해 직접 타이핑을 했었다. 그런데 만약 local 내의 코드를 수정해야 하는 경우라면 어떻게 해야 할까?
import * as passport from 'passport';
import * as bcrypt from 'bcrypt';
import { Strategy } from 'passport-local';
import User from '../models/user';
export default () => {
passport.use('local', new Strategy({
usernameField: 'userId',
passwordField: 'password',
session: false, // 세션에 로그인 정보 저장 안할 때 false
passReqToCallback: true, // req 객체를 passport 인증 시 활용
}, async (req, userId, password, done) => {
try {
const user = await User.findOne({ where: { userId } });
if (!user) return done(null, false, { message: '존재하지 않는 사용자입니다!' });
const result = await bcrypt.compare(password, user.password);
if (result) return done(null, user);
return done(null, false, { message: '비밀번호가 틀립니다.' });
} catch (err) {
console.error(err);
return done(err);
}
}))
};
기존 코드에서 strategy 안에 session과 passReqToCallback 속성을 추가했다. passReqToCallback 속성을 true로 설정하게 되면 req객체를 passport 인증시 활용해야 하기 때문에 콜백함수에 req 매개변수도 추가되어야 한다. 여기서 문제가 발생한다.
export interface IStrategyOptions {
usernameField: string;
passwordField: string;
session?: boolean;
passReqToCallback?: false;
}
우리가 사용하는 인터페이스에서는 passReqToCallback 속성을 false로 했었다. 이를 true로 바꾸게 된다면 이로 인해 수정되는 모든 코드들을 다 수정해야 한다.
즉 속성의 옵션을 그때그때 다르게 사용하게 되는 경우 그때마다 작업해야 하는 요소가 생기게 되는 것이고, 이는 매우 비효율적인 방법이다. 이렇게 모듈들은 가변적인 매개변수를 받을 수 있고, 이런 다양한 케이스에 맞는 타이핑을 한다.
/**
* 남들에게 배포하는 용은 아님. 이건 개발용
* 배포할 때는 리덕스 따라가면서 알려드림..?
* 모든 부분을 타이핑할 필요 전혀 없음. 내가 사용하는 코드 부분만 작성
* local.ts 코드 보면서 적합한 타입 직접 정의하기
*/
declare module "passport-local" { // delcare module은 실제 모듈의 이름과 같게 해야 에러나지 않음
import { Request } from 'express';
import { Strategy as PassportStrategy } from 'passport';
// 인터페이스 이름은 실제 모듈과 이름을 같게 만듦
export interface IVerifyOptions { // export로 확장성 고려
[key: string]: any;
}
export interface IStrategyOptions {
usernameField: string;
passwordField: string;
session?: boolean;
passReqToCallback?: false;
}
export interface IStrategyOptionsWithRequest {
usernameField: string;
passwordField: string;
session?: boolean;
passReqToCallback: true;
}
export interface Done {
(error: any, user?: any, options?: IVerifyOptions): void;
}
export interface VerifyFunction {
(username: string, password: string, done: Done): void | Promise<any>;
}
// req를 가장 앞 매개변수에 사용해야 하는 경우가 필요할 때, 오버로딩할 수 있는 인터페이스 생성
export interface VerifyFunctionWithRequest {
(req: Request, username: string, password: string, done: Done): void | Promise<any>;
}
export class Strategy extends PassportStrategy {
// constructor(options: IStrategyOptions | IStrategyOptionsWithRequest, verify: VerifyFunction | VerifyFunctionWithRequest) // | 연산자 사용하면 에러 발생 가능함
constructor(options: IStrategyOptions, verify: VerifyFunction)
constructor(options: IStrategyOptionsWithRequest, verify: VerifyFunctionWithRequest)
}
}
728x90
LIST
'개발자 도전기 > [STUDY] JS || TS' 카테고리의 다른 글
node.js | axios | 엑시오스 더 깊게 이해하고 사용하자..! (0) | 2022.10.07 |
---|---|
nuxt.js | shopping web-app | 기본부터 차근차근 (1) | 2022.09.19 |
ts-node | NodeBird | 타입 없는 라이브러리 타이핑하기 (0) | 2022.05.03 |
ts-node | NodeBird | 라우터 만들기(3) (0) | 2022.05.03 |
ts-node | NodeBird | 라우터 만들기(2) (0) | 2022.05.02 |
댓글