Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

177
Visualizações
Bluebird / Typescript Error: 'this' context of is not assignable to method's 'this'

I have a series of methods (some asynchronous and some not) that I would like to use bluebird.each to process in order. Here is a dumbed down example:

import bluebird from 'bluebird';

const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
class Template {
  propertyA!: number;
  propertyB!: number;
  constructor() {}
  async methodA() {
    this.propertyA = 10;
    console.log({ thisArgInA: this, propertyA: this.propertyA });
    await delay(500);
    return this.propertyA;
  }
  methodB() {
    this.propertyB = this.propertyA * 100;
    console.log({ thisArgInB: this, propertyB: this.propertyB });
    return this.propertyB;
  }
}

const instance = new Template();

const sequence = [instance.methodA, instance.methodB];

(async function main() {
  await bluebird.each(sequence, (fn) => {
    const result = fn.call(instance);
    console.log({ result });
  });
})();

This produces this error I do not understand:

index.ts:27:20 - error TS2684: The 'this' context of type '(() => Promise<number>) | (() => number)' is not assignable to method's 'this' of type '(this: Template) => Promise<number>'.
  Type '() => number' is not assignable to type '(this: Template) => Promise<number>'.
    Type 'number' is not assignable to type 'Promise<number>'.

27     const result = fn.call(instance);

I thought maybe it is because bluebird.each accepts either values or promise that resolve to values the compiler can't reconcile things, but the only solution I thought of there was to strongly type the return values"

async methodA: Promise<number> { /*...*/ }
methodB: number { /*...*/ }

But that didn't change anything. Also I note the following:

  • I have to provide context here, because invoking the functions in the each callbacks loses connection to the Template as this
  • When methodA is synchronous (remove the async keyword, remove the delay(), just return this.propertyA, this works fine.
  • When I remove the return statements things work fine.
  • When I change fn.call(instance) to fn.bind(instance)() it works fine

How can I satisfy the compiler so it knows how to call these functions with the provided context.

Is there an easier way to call these methods in sequence so their connection to this is maintained?

StackBlitz Example

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

It may help to look at the inferred types:

  • sequence: (((this: Template) => number) | ((this: Template) => Promise<number>))[] or just ((() => Promise<number>) | (() => number))[]
  • fn: ((this: Template) => number) | ((this: Template) => Promise<number>) or just (() => Promise<number>) | (() => number)
  • .call: <Template, [], number>(this: (this: Template) => number, thisArg: Template): number

and we can see that the type of the .call() expression is not what we expect - the compiler wants a function returning a number, and complains since fn can alternatively return a Promise<number>. This is probably due to a TypeScript bug when dealing with inferring the return type of function union types. It might be related to the subtle difference between X => A | B and (X => A) | (X => B).

We can fix this by writing

  • const result = fn.call<Template,[],number|Promise<number>>(instance); or
  • …(fn: () => number | Promise<number>)) => … or
  • const sequence: (() => number | Promise<number>)[]
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda