crimson73
crimson73

Reputation: 83

TS2345 when passing argument to resolve()

I'm trying to locally run the unit tests for https://github.com/FullHuman/purgecss, but I'm getting an error:

error TS2345: Argument of type 'Stats | undefined' is not assignable to parameter of type 'Stats | PromiseLike<Stats>'

The line it's referring to calls the resolve() callback of a promise with a potentially undefined argument. However, VSCode seems to indicate that the type signature for the argument to resolve() includes undefined, so it shouldn't be throwing a type error. Is there any good way to debug this more, or see authoritatively the type signature for resolve()?

This is the code block that's throwing a type error:

function runWebpack(options: Configuration): Promise<webpack.Stats> {
  const compiler = webpack(options);
  return new Promise<webpack.Stats>((resolve, reject) => {
    compiler.run((err?: Error, stats?: Stats) => {
      if (err) reject(err);
      if (stats?.hasErrors()) reject(new Error(stats.toString()));
      resolve(stats); // error TS2345: Argument of type 'Stats | undefined' is not assignable to parameter of type 'Stats | PromiseLike<Stats>'
    });
  });
}

Upvotes: 0

Views: 292

Answers (1)

VLAZ
VLAZ

Reputation: 29090

VSCode seems to indicate that the type signature for the argument to resolve() includes undefined

This is not Visual Studio Code but the TypeScript compiler. Since you've declared stats as an optional parameter of type Stats that indicates that it's possible to not pass that parameter, so the real type is Stats | undefined. However, since you use new Promise<webpack.Stats> this constrains the value possible from resolving this promise to be Stats, never undefined.

There is not enough information for TypeScript to conclude that resolve(stats) would only be called if stats is not undefined. You should re-structure your conditionals to exclude the undefined value:

compiler.run((err?: Error, stats?: Stats) => {
  if (err) reject(err);
  if (stats)
    if (stats.hasErrors()) reject(new Error(stats.toString()));
    else resolve(stats);
});

Upvotes: 1

Related Questions