L'exemple suivant fonctionne (en JavaScript), mais je ne parviens pas à obtenir les bons types de retour dans TypeScript. En fonction de l'objet usine, il doit connaître le type de retour correct de la fonction "func".

Nous voulons utiliser ce modèle pour ajouter et obtenir dynamiquement des DataLoaders.

class Dog {
  bark() { console.log("wuff")}
}
class Cat {
  miau() { console.log("miau")}
}

class FactoryItem<T extends () => {}> {
  constructor(public func: T) {}
}

class Factories {
  factories = new Map();
  
  add<T extends () => {}> (factories: FactoryItem<T>) {
    this.factories.set(factories,factories.func())
  }

  get<T extends FactoryItem<()=>{}>>(factory:T):ReturnType<typeof factory.func> {  // this is not working
    return this.factories.get(factory)
  }
}

const factoryA = new FactoryItem(() => new Dog());
const factoryB = new FactoryItem(() => new Cat());

const factories = new Factories();
factories.add(factoryA)
factories.add(factoryB)

factories.get(factoryA).bark(); // typescript is not happy
//factorys.get(factoryB).bark(); // this must fail
factories.get(factoryB).miau(); // typescript is not happy


0
brenkdar 14 mars 2021 à 16:24

1 réponse

Meilleure réponse

Dans le type de retour de cette fonction-

  get<T extends FactoryItem<()=>{}>>(factory: T):ReturnType<typeof factory.func> {  // this is not working
    return this.factories.get(factory)
  }

Vous prétendez que le type de retour de get est le type de retour de factory.func - mais il ne s'agit que d'un type de constante qui est non dépendant sur le type générique .

Si vous voulez que votre type de retour soit influencé par le type générique, vous devez utiliser le type générique, alias T -

  get<T extends FactoryItem<()=>{}>>(factory: T):ReturnType<T['func']> {
    return this.factories.get(factory)
  }

N'oubliez pas que le contexte du générique lors de l'utilisation de la fonction générique est uniquement capturé par le type générique (dans ce cas T) - donc chaque fois que vous souhaitez construire un type en fonction du contexte capturé, vous devez le faire en fonction du paramètre de type générique (dans ce cas T).

Voici un aire de jeux lien < / a>

1
Chase 14 mars 2021 à 15:00