J'essaie de trouver un moyen d'injecter un objet dans un autre objet (injection de dépendance), dans lequel l'objet conteneur peut retourner le bon injecté type d'objet et pas besoin de passer explicitement les types à la fonction (inférence de type).
Pour s'assurer que les objets injectés ont une interface commune et un comportement par défaut, ils seront des instances d'une classe abstraite.
Étant donné que j'aurais besoin d'un tel comportement à un endroit ponctuel, je voudrais éviter d'utiliser un cadre d'injection de dépendances pour le faire.
Il me semble que ce dont j'ai besoin, c'est de définir le type générique lors de l'instanciation de l'objet, car les paramètres génériques ne peuvent pas être redéfinis par la suite. Par conséquent, j'aurais besoin d'utiliser un usine (
new()
interface)
Voici un exemple. [Testez-le dans Typescript Playground](https://www.typescriptlang.org/play/index.html#src=class%20ArrayClassAbstract%3CMYTYPE%3E%20%7B%0D%0A%20%20%20%20public%20arr%3A%20Array%3CMYTYPE%3E%20%3D%20%5B%5D%0D%0A%20%20%20%20constructor(element%3A%20MYTYPE)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.arr.push(element)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aclass%20ArrayClass%3CMYTYPE%3E%20extends%20ArrayClassAbstract%3CMYTYPE%3E%20%7B%0D%0A%20%20%20%20test()%20%7B%20%0D%0A%20%20%20%20%20%20%20%20return%20this.arr%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aclass%20SomeOtherArrayClass%3CMYTYPE%3E%20extends%20ArrayClassAbstract%3CMYTYPE%3E%20%7B%0D%0A%20%20%20%20test()%20%7B%20%0D%0A%20%20%20%20%20%20%20%20return%20this.arr%20%2B%20%22something%20different%22%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20createMyClass%3CMYTYPE%3E%0D%0A%20%20%20%20(className%3A%20%7B%20new%20%3CMYTYPE%3E(element%3A%20MYTYPE)%3A%20ArrayClassAbstract%3CMYTYPE%3E%20%7D%2C%20element%3A%20MYTYPE)%20%7B%20%0D%0A%20%20%20%20return%20new%20className%3CMYTYPE%3E(element)%3B%0D%0A%7D%0D%0A%0D%0Alet%20a%20%3D%20createMyClass(ArrayClass%2C%20%22hop!%22)%3B%20%20%20%2F%2F%20type%3A%20%7BArrayClassAbstract%3Cstring%3E%7D%0D%0Aa.test()%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Doesn't%20work...%20%22test%22%20doesn't%20exist%20in%20ArrayClassAbstract%0D%0A%0D%0A%0D%0Afunction%20createMyClass2%3CT%20extends%20ArrayClassAbstract%3Cstring%3E%3E%0D%0A%20%20%20%20(className%3A%20%7B%20new%20(element%3A%20string)%3A%20T%20%7D%2C%20element%3A%20string)%20%7B%20%0D%0A%20%20%20%20return%20new%20className(element)%3B%0D%0A%7D%0D%0A%0D%0Alet%20b%20%3D%20createMyClass2(ArrayClass%2C%20%22hop!%22)%3B%20%20%2F%2F%20type%3A%20%7BArrayClass%3Cany%3E%7D%0D%0Ab.test()%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Works%20but%20array%20elements%20typed%20as%20%22any%22) . Pour faire simple, je recherche createMyClass2
pour retourner un objet typé ArrayClass<string>
sans spécifier explicitement le type lors de son appel (inférence de type).
On peut considérer que ArrayClass
et ArrayClassAbstract
sont des sortes de plugins définis dans différents NPM par exemple.
class ArrayClassAbstract<MYTYPE> {
public arr: Array<MYTYPE> = []
constructor(element: MYTYPE) {
this.arr.push(element);
}
}
class ArrayClass<MYTYPE> extends ArrayClassAbstract<MYTYPE> {
test() {
return this.arr;
}
}
class SomeOtherArrayClass<MYTYPE> extends ArrayClassAbstract<MYTYPE> {
test() {
return this.arr + "something different";
}
}
function createMyClass<MYTYPE>
(className: { new <MYTYPE>(element: MYTYPE): ArrayClassAbstract<MYTYPE> }, element: MYTYPE) {
return new className<MYTYPE>(element);
}
let a = createMyClass(ArrayClass, "hop!"); // type: {ArrayClassAbstract<string>}
a.test(); // Doesn't work... "test" doesn't exist in ArrayClassAbstract
Bon type générique, mauvais type de classe...
function createMyClass2<T extends ArrayClassAbstract<string>>
(className: { new (element: string): T }, element: string) {
return new className(element);
}
let b = createMyClass2(ArrayClass, "hop!"); // type: {ArrayClass<any>}
b.test(); // Works but array elements typed as "any"
Bon type de classe, mauvais type générique. Je ne sais pas s'il y a quelque chose de mal dans ma façon de déclarer la fabrique, ou si je suis victime des limitations de Typescript...
Une idée ?