키를 기반으로 클래스의 인스턴스를 반환하려고하는데 클래스 사용자 지정 메서드에 액세스 할 수 없습니다.
타이프 스크립트 : 3.8.3
코드는 다음과 같습니다.
abstract class BaseProvider {
foo!: string
}
class ProviderA extends BaseProvider {
public testA(): string {
return this.foo + 'a'
}
}
class ProviderB extends BaseProvider {
public testB(): string {
return this.foo + 'b'
}
}
type Provider = ProviderA | ProviderB
const providers = {
a: ProviderA,
b: ProviderB,
}
function useProvider<T extends keyof typeof providers>(key: T): Provider {
const defaultProvider = providers.a
const providerByKey = providers[key]
if (!providerByKey) {
console.warn(`Provider "${key}" doesn't exists.`)
return new defaultProvider()
}
return new providerByKey()
}
const providerA = useProvider('a')
/**
* Property 'testA' does not exist on type 'Provider'.
* Property 'testA' does not exist on type 'ProviderB'.
*/
providerA.testA()
const providerB = useProvider('b')
/**
* Property 'testB' does not exist on type 'Provider'.
* Property 'testB' does not exist on type 'ProviderA'.
*/
providerB.testB()
나는 기대한다 :
useProvider('a')
반환 new ProviderA()
하고 메서드에 액세스 할 수 있습니다 testA
.
useProvider('b')
반환 new ProviderB()
하고 메서드에 액세스 할 수 있습니다 testB
.
인스턴스 대신 클래스를 반환하는 "솔루션"을 찾았지만 필요한 것은 아닙니다.
function useProvider<T extends keyof typeof providers>(key: T): typeof providers[T] {
return providers[key]
}
const providerA = new (useProvider('a'))()
providerA.testA()
솔루션에 매우 가깝습니다 T
. 반환 유형과 사이의 관계를 지정하기 만하면 됩니다. 반환 유형은 providers
key 의 옵션에 있는 클래스의 인스턴스 유형 T
이므로InstanceType<typeof providers[T]>
유일한 문제는 InstanceType<typeof providers[T]>
컴파일러가에서 반환하는 것과 동일 하다는 것이 컴파일러에 명확하지 않다는 new providerByKey()
것입니다. 따라서 구현을 위해 더 관대 한 서명을 유지하면서 유형 어설 션을 사용하거나 특수 반환 유형을 전용 공용 서명으로 이동해야합니다. 내가 아래에서 한 것처럼 서명. 이 접근 방식은 유형 어설 션을 사용하지 않지만 반환하는 내용이 실제로 더 복잡한 공개 서명과 일치하는지 확인하는 것과 관련하여 사용자 자신이 있음을 의미합니다)
function useProvider<T extends keyof typeof providers>(key: T): InstanceType<typeof providers[T]>
function useProvider<T extends keyof typeof providers>(key: T): Provider {
const defaultProvider = providers.a
const providerByKey = providers[key]
if (!providerByKey) {
console.warn(`Provider "${key}" doesn't exists.`)
return new defaultProvider()
}
return new providerByKey()
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다