inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)

게시글 작성 API 연결

(솔루션 수정)'tsyringe' Error: TypeInfo not known for "클래스명"

789

Truestar

작성한 질문수 68

0

진작에 질문을 남겼어야 했는데, 애러 해결이 어려워 너무 지체되네요. 첫 질문 남기게 되었습니다.

 

문제의 요지
: 추측 하기로container.resolve 가 vue 와 라이프사이클 에 순서때문인지, 다른 이유가 있는지 DI 가 안됩니다. 

 

Menu.vue 디버깅

강의내용에도 있듯 tsyringe 는@singleton 이 달려있는 클래스를 컨테이너에 등록 후, 클래스 자체를 DI 키로 사용할 수 있다고 알고있습니다. 디버깅 상황에서 보다시피container 내부 _registryMap 안에 AuthorityApi 클래스가 정상등록 된 것을 확인할 수 있었습니다.

image

 

하지만 Break-point 된 container.resolve 처리가 안되어 아래처럼 애러가 발생합니다. 아래는 다음줄로 가지않고, 이벨류에이터로 실행한 모습이구요, AuthorityApi를 찾아올 수 없다 합니다.

image.png

Error: TypeInfo not known for "AuthorityApi"
    at http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:746:17
    at InternalDependencyContainer2.construct (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:751:6)
    at InternalDependencyContainer2.resolveRegistration (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:573:90)
    at InternalDependencyContainer2.resolve (http://localhost:4000/node_modules/.vite/deps/tsyringe.js?v=a355aabe:500:25)
    at eval (eval at setup (http://localhost:4000/src/widgets/Menu.vue:28:26), <anonymous>:1:11)
    at setup (http://localhost:4000/src/widgets/Menu.vue:28:26)
    at callWithErrorHandling (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:1884:19)
    at setupStatefulComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:8253:25)
    at setupComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:8214:36)
    at mountComponent (http://localhost:4000/node_modules/.vite/deps/chunk-VJROVW5H.js?v=a355aabe:5604:7)

 

해결방법을 tsyringe 공식 깃헙이슈, 구글링, 스택오버플로 몽창 뒤져봐도 힌트얻기가 참으로 힘드네요. AI 센세는 그저 스택오버플로 내용만 읊어줍니다.

이것에 원인을 알 수 있을까요? 실마리만 얻어도 해결하기 수월할텐데, 몇일 째 어째야 되나 고민입니다. 도움을 얻을 수 있을까요?

 

: Source-Code

src-front 소스코드

주의: 개인 npm lib 가 포함되어 node_modules 을 포함한 체 그대로 압축된 파일입니다. npm i 인스톨 없이 앱을 실행해야될거라 예상합니다.

 

도움을 구합니다. 감사드려요.

vue.js tsyringe typescript ts container resolve di inject

답변 2

0

Truestar

솔루션 수정본

⚠ 기존 댓글에 정리된 내용이 적절치 않아 삭제 후, 실제 동작하는 방법에 대해 다시 정리합니다.

다음은 알려진 OOP 인터페이스 분리 패턴(ISP)을 TS기반 tsyringe 에서 추상클래스를 InjectionToken 으로 사용하는 방법입니다.

 

updates: 

  • 24-09-19: InjectionToken 형 변환 시, as InjectionToken 에서 `as InjectionToken 또는 as unknown as InjectionToken 으로 변경

 

1. extends AbstractClass

: 추상클래스를 상속,확장합니다.

abstract class Super {}

class Impl extends Super {}

 

2. 구현체 클래스에 @registry([..]) 추가

@singleton()
// ✅ @registry 에 직접 연관된 부모클래스(추상체)를 지정해야 @inject 를 통해 주입이 가능해집니다.
@registry([
  {
    // 💡 tsyringe 는 추상클래스 등록을 지원하지 않아 타입미스매치 애러 발생.
    //    해결은 unknown as InjectionToken 으로 강제 케스팅 후 등록이 가능함.
    // 1안
    token: Super as InjectionToken, 
    // 또는 2안
    token: Super as unknown as InjectionToken,
    useClass: Impl,
  },
])
class Impl extends Super {}

 

3. 사용

export class ConstructorInjectionWithTsyringe {
  constructor(
    @inject(Impl)
    readonly sup: Super,
  ) {}
}

 

동작확인

아래는 질문의 소스코드 디버깅 상황에서 캡쳐된 이미지입니다. 추상클래스 HttpClient 타입 맴버변수에, 구현체 AxiosHttpClient 인스턴스가 정상 주입된 것을 확인할 수 있었습니다.

image.png

 

0

Truestar

:: 추가이슈 해결 ::


문제
: 추상클래스를 container.resolve 인수로 대입 시, 반환된 인스턴스가 any 타입으로 추론됩니다.

: AppLogger 가 추상클래스 일때, InjectionToken 으로 형변환 시, 변수 log 는 any 타입으로 추론됩니다. 이로인해 IDE 의 메서드 추론기능을 사용할 수 없습니다.

// 🚫 log: any 
const log = container.resolve(AppLogger as InjectionToken)

 

해결:

InjectionToken 타입의 구성은 다음과 같습니다.

declare type InjectionToken<T = any> = constructor<T> | string | symbol | DelayedConstructor<T>;

이 중에 constructor<T> 를 사용해서 강제케스팅 합니다.

 

적용코드:
import { container } from 'tsyringe'
import type { constructor } from 'tsyringe/dist/typings/types'

// log: AppLogger ✅
const log = container.resolve(AppLogger as constructor<AppLogger>)  

 

0

호돌맨

import {AxiosHttpClient, HttpClient, type ResponseHandlerOptions} from '@/features'

@singleton()
export class AuthorityApi {
  constructor(@inject(HttpClient) readonly httpClient: AxiosHttpClient) {}

    // 생략
}

AuthorityApi의 생성자 주입이 안되는 상태입니다.

때문에 외부에서 container.resolve(AuthorityApi)가 안먹히는 상황입니다.

위 코드와 같이 AxiosHttpClient를 직접 지정해서 해결할 수 있습니다.

혹은 tsyringe 예제 문서와 같이 interface를 이용해서 주입할수도 있긴합니다.

관련링크: https://github.com/microsoft/tsyringe?tab=readme-ov-file#example-with-interfaces

0

Truestar

앗... 한참 정리중에 답글을 달아주셨군요... 해결상태로 종결하겠습니다!

0

Truestar

일반적인 OOP 방식처럼, inject 데코레이터에 구현체클래스, 필드변수타입에 추상체클래스 선언이 가능한 방법이 있었습니다. 너무 해맨것 치고 너무 해결방법이 간단해 허탈했고, 알려주신 방법이 다른 경우에서 잘 안되는거 같아, 용법을 새-댓글에 다시 정리하게 되었어요.

참고: microsoft/tsyringe: @registry

Deprecated 관련 사항들

0

182

2

깃헙 collaboator 초대 관련

0

141

1

logout 후에 login 페이지 이동은 어디서 시켜주는건가요?

0

272

1

다중 데이터를 삭제 할 때

0

336

2

querydsl Q class 이슈

0

490

2

Windows WSL Vue 설정

2

289

1

Dip, @transactional

0

233

1

[vite] http proxy error: /auth/login

0

1190

2

로그인 하고 나서 GET요청으로 메인페이지 요청

0

296

2

GitHub Collaborator 초대 관련

0

347

2

Window에서 Vue.js 설정

0

386

2

collaboator로 초대받을 수 있을까요??

0

345

2

SecurityMockContext 로부터 유저 정보를 가져오기

0

307

1

섹션9 프론트의 코드를 보고싶습니다,,,

0

459

1

Spring Security - defaultSuccessUrl 질문

0

669

1

강의 화면이 나오지 않습니다. 음성과 자막만 나와요

0

354

1

JPAQueryFactory(em)의 객체 생성자 오류에 대해서 질문이 있습니다ㅜㅜ

0

756

2

ExceptionHandler가 AccessDeniedHandler(Http403Handler)를 먹어버리는 현상

0

1218

2

섹션10 언제 나오나요?

0

515

1

CommentService에서 Repository를 호출하지 않는데도

0

371

1

Editor....를 활용한 패턴에 질문있습니다.

0

531

1

섹션9 vue

0

495

2

Post에 edit 메서드 삼항연산자 질문

0

510

2

@Configuration WebMvcConfig클래스에대해

0

616

1