Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

174
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!