Alan
Alan

Reputation: 2639

Let variable assinged inside Promise constructor is being marked as undefined by Typescript

I am defining a let variable called resolver which then I want to assign inside a promise constructor function.

interface Request {
    ids: string[];
    resolver: () => void;
    promise: Promise<unknown>
}

class Foo {
    public requests: Request[] = [];

    public createPromise = (ids: string[]) => {
        let resolver;

        const promise = new Promise((r) => { resolver = r; });

        this.requests.push({ ids, resolver, promise });

        return promise;
    };
}

But I'm getting the following TypeScript error for the resolver when I try to push the object to the requests list:

Type 'undefined' is not assignable to type '() => void'.ts(2322)

The resolver variable I am assigning inside the promise constructor is being marked as undefined.

Upvotes: 1

Views: 125

Answers (1)

brunnerh
brunnerh

Reputation: 184336

There are a few things that need to be changed.

  • The local resolver variable should be given an explicit type that matches that of the request interface.
  • You need to assert (!) that the variable will be assigned. The assignment happens in a callback function and TS has not way to know when this function will be called. A different class might take a similar callback in the constructor and not call it immediately.
  • The function in the request interface should take a value argument of a matching type to the promise. If you do not need a resolved value, you can use Promise<void> instead.
interface IRequest {
    ids: string[];
    resolver: (value: unknown) => void;
    promise: Promise<unknown>
}

class Foo {
    public requests: IRequest[] = [];

    public createPromise = (ids: string[]) => {
        let resolver!: (value: unknown) => void;

        const promise = new Promise((r) => { resolver = r; });

        this.requests.push({ ids, resolver, promise });

        return promise;
    };
}

(Renamed interface to not conflict with fetch API Request.)


Example of the assignment issue:

class FakePromise {
  constructor(executor) {
    // *crickets*
  }
}

let resolver1;
new Promise(r => resolver1 = r);
console.log(resolver1); // function () ...

let resolver2;
new FakePromise(r => resolver2 = r);
console.log(resolver2); // undefined

Upvotes: 2

Related Questions