Le site Types de caractères TypeScript pour Map
soutien uniquement Map<K, V>
donde K
est le type de clé, V
est le type de valeur, et il n'y a pas d'autre corrélation entre eux. Ainsi, si vous utilisez simplement Map
en l'état, vous ne pouvez pas faire en sorte que le compilateur TypeScript applique des contraintes supplémentaires.
D'après ma lecture de votre question, je comprends que votre contrainte est que la clé doit être un type constructeur (éventuellement abstrait), et que pour chaque clé, la valeur doit être un constructeur (nécessairement concret) d'un type compatible. Et puisque votre code d'exemple n'utilise que le set()
les typages minimums pour que le code de votre exemple se comporte comme souhaité ressemblent à ceci :
interface MySpecialMap {
set<T extends object>(
k: abstract new (...args: any) => T,
v: new (...args: any) => T
): this;
}
interface MySpecialMapConstructor {
new(): MySpecialMap;
}
const MySpecialMap: MySpecialMapConstructor = Map;
Ici, j'ai défini le MySpecialMap
pour être juste le Map
au moment de l'exécution, mais je lui ai donné le type MySpecialMapConstructor
qui construit des instances de MySpecialMap
. Le site MySpecialMap
n'a qu'une seule méthode, set()
qui est Générique dans le type T
des instances de la classe de base. Le site k
est un paramètre éventuellement abstract
Constructeur de type T
tandis que les v
est un constructeur nécessairement concret de type T
instances.
Démontrons que cela fonctionne comme souhaité :
abstract class BaseA { a() { } }
class ConcreteA1 extends BaseA { a1() { } }
class ConcreteA2 extends BaseA { a2() { } }
abstract class BaseB { b() { } }
class ConcreteB extends BaseB { b1() { } }
const map = new MySpecialMap();
map.set(BaseA, ConcreteA1); // ok
map.set(BaseA, ConcreteA2); // ok
map.set(BaseB, ConcreteB); // ok
map.set(BaseA, ConcreteB); // error
// Property 'a' is missing in type 'ConcreteB' but required in type 'BaseA'
map.set(BaseA, BaseA); // error
// Cannot assign an abstract constructor type to a non-abstract constructor type.
Ça a l'air bon !
Après cela, vous voudrez probablement ajouter des typages similaires pour get()
ou toute autre méthode dont vous avez besoin. Vous pouvez également modifier la signature de l'appel de la méthode set()
pour spécifier des constructeurs à argument zéro ou toute autre contrainte que vous voulez faire respecter. Mais nous espérons que cela vous aidera à démarrer.
Lien du terrain de jeu vers le code