Вы довольно близки к решению, вам просто нужно указать связь между типом возвращаемого значения и T
. Тип возврата будет типом экземпляра класса, расположенного в параметре providers
в ключе T
, поэтому InstanceType<typeof providers[T]>
Единственная проблема в том, что InstanceType<typeof providers[T]>
не ясно для компилятора. то же самое, что возвращается new providerByKey()
, поэтому вам придется либо использовать утверждение типа, либо переместить специализированный тип возврата в выделенную подпись publi c, сохраняя при этом вашу более разрешительную подпись для подписи реализации, как я сделал ниже . Обратите внимание, что хотя этот подход не использует утверждения типа, это означает, что вы сами по себе можете гарантировать, что то, что вы возвращаете, действительно согласуется с более сложной подписью publi c)
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()
}
Ссылка на игровую площадку