Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common pattern when variable is used before being assigned

Tags:

typescript

I have a module

import pino, { Logger } from 'pino';

let logger: Logger;

if (process.env.NODE_ENV === 'production') {
    const dest = pino.extreme();
    logger = pino(dest);
}

if (process.env.NODE_ENV === 'development') {
    // @ts-ignore
    logger = pino({ prettyPrint: { colorize: true } });
}

...

export default logger;
// ^^^ [ts] Variable 'logger' is used before being assigned. [2454]

Here is no any situation when logger is undefined, but even if it will be undefined it is suted for me

How to resolve the TypeScript error at the end:

Variable 'logger' is used before being assigned. [2454]

I've rewritten my code but the error still here

import pino, { Logger } from 'pino';

let logger: Logger;

if (process.env.NODE_ENV === 'production') {
    const dest = pino.extreme();
    logger = pino(dest);
} else 

if (process.env.NODE_ENV === 'development') {
    // @ts-ignore
    logger = pino({ prettyPrint: { colorize: true } });
} else

if (process.env.NODE_ENV === undefined) {
    throw new Error('Logger must be initialized! Set up process.env.NODE_ENV');
}

if (logger) { // <-- Variable 'logger' is used before being assigned. [2454]
   // configuring process
}

export default logger;

Even in another way

import pino, { Logger } from 'pino';

let logger: Logger;

function configureProcess(theLogger: Logger) {
  // setup process with theLogger
}

if (process.env.NODE_ENV === 'production') {
    const dest = pino.extreme();
    logger = pino(dest);
    configureProcess(logger); // <-- code duplication
} else if (process.env.NODE_ENV === 'development') {
    // @ts-ignore
    logger = pino({ prettyPrint: { colorize: true } });
    configureProcess(logger); // <-- code duplication
}

if (process.env.NODE_ENV === undefined) {
    throw new Error('Logger must be initialized! Set up process.env.NODE_ENV');
}

export default logger;
// ^^^ [ts] Variable 'logger' is used before being assigned. [2454]

I feel like a fighter against TypeScrit instead of developer - so many dances to solve a problem which is not a problem in reality (

like image 666
Vadim Avatar asked Nov 21 '18 15:11

Vadim


1 Answers

but even if it will be undefined it is suted for me

I would suggest that having logger be undefined is not a good idea (more below), but based on your statement above:

Make that explicit, to the compiler and to maintainers of the code:

switch (process.env.NODE_ENV) {
    case 'production':
        const dest = pino.extreme(); // logs to stdout with no args
        logger = pino(dest);
        break;
    case 'development':
        // @ts-ignore
        logger = pino({ prettyPrint: { colorize: true } });
        break;
    default:
        logger = undefined; // That's fine
        break;
}

(Doesn't have to be switch, if/else if/else works too.)

Also note that you'll need to allow logger to have the value undefined, as VinceOPS points out:

let logger: Logger | undefined;

Note: This means that anything using logger has to allow for it having the value undefined. I wouldn't do that if I were you. Instead:

  1. If you only need to support the two configurations you list, either:

    1. Only check for one of them and then assume the other:

      if (process.env.NODE_ENV === 'development') {
          case 'development':
              // @ts-ignore
              logger = pino({ prettyPrint: { colorize: true } });
      } else { // production
              const dest = pino.extreme(); // logs to stdout with no args
              logger = pino(dest);
      }
      

      or

    2. Throw an error in the third branch:

      switch (process.env.NODE_ENV) {
          case 'production':
              const dest = pino.extreme(); // logs to stdout with no args
              logger = pino(dest);
              break;
          case 'development':
              // @ts-ignore
              logger = pino({ prettyPrint: { colorize: true } });
              break;
          default:
              throw new Error("process.env.NODE_ENV must be either 'production' or 'development' to use this module");
      }
      
  2. If you want to support all three possibilities (production, development, or neither), initialize logger to a valid Logger in the third branch as well, perhaps a "do nothing" logger.

That would be much better than letting logger be undefined.

like image 96
T.J. Crowder Avatar answered Oct 27 '22 00:10

T.J. Crowder