У меня есть функция, которая принимает что угодно в качестве параметра, но если она получает function
(с прототипом), она должна вернуть экземпляр этой функции (или класса, поскольку они являются функциями). Если нет, он может искать что-либо, назначенное этому ключу, внутри карты и возвращать его.
The super simplified code would look something like (playground):
// Go check service.get() method
const isConstructable = (fn: any) => typeof fn === 'function' && 'prototype' in fn;
class Animal {
name: string | undefined
constructor(name?: string){
this.name = name;
}
}
const service = new (class Service {
map = new Map()
set(key: any, value: any = key) {
return this.map.set(key, value)
}
get<T>(key: { new (): T }): T {
const ToResolve = this.map.get(key);
if (isConstructable(ToResolve)) {
return new ToResolve();
}
return ToResolve;
}
})
service.set('bob', new Animal('Bob'))
service.set(Animal);
const genericAnimal = service.get(Animal)
const bob = service.get('bob') // Argument of type 'string' is not assignable to parameter of type 'new () => unknown'
console.log(genericAnimal instanceof Animal)
console.log(bob instanceof Animal)
Я читал Использование типов классов в обобщениях а> и нашел этот код
function create<T>(c: { new (): T }): T {
return new c();
}
Это работает хорошо, но мне нужно, чтобы get(key)
принимал не только конструкторы, но и любые примитивы, принимаемые Map
, например:
const jane = {} // object reference, since TS won't let me use symbols
service.set(jane, class Jane extends Animal {
constructor() {
super('Jane')
}
})
console.log(service.get(jane).name === 'Jane')
Таким образом, я получаю ошибки компиляции, такие как Argument of type 'string' is not assignable to parameter of type 'new () => unknown'
Также пробовал с: get<T>(key: T): T extends Function ? T : unknown
, что, очевидно, не работает, но кажется таким близким :(
Должен ли я создавать определенный тип для параметра key
? Дайте определение перегрузкам? Как?
заранее спасибо
const jane = Symbol("jane");"
работает, верно? В чем проблема? - person jcalz   schedule 02.11.2020service.get(jane)
вернет значение типаunknown
в нужном вам решении, верно? Таким образом, вы не можете написатьservice.get(jane).name
, потому чтоunknown
не имеет свойстваname
. Так что же вы действительно ищете? - person jcalz   schedule 02.11.2020service.get()
. Я согласен с тем, чтоget("bob")
возвращает неизвестное, пока TS не жалуетсяArgument of type 'string' is not assignable to parameter of type 'new () => unknown'
, Иservice.get(Animal)
возвращает животное. - person Frondor   schedule 02.11.2020