by

When Jest and TypeScript tell you “missing initializer in const declaration”

Reading Time: 3 minutes

While I generally avoid TypeScript, I’m willing to acknowledge that there might be edge cases where it could be useful. And in an effort to actually learn how to make it useful, I’m converting one of my linguistic / NLP node packages to TypeScript (Methodius, if you care).

I’d already used JSDoc heavily throughout the project, so 98% of my work was making types. I only had one function where logic needed to be addressed at all.

I figured that re-tweaking Jest to read .ts files instead of js files would take a few minutes, and then my unit tests would continue to report a bunch of green check marks.

So imagine my surprise when Jest threw an error on a friggin’ constant of all things…

Writing TypeScript is basically like trying to use a computer with a bi-polar goat in the room. You know you're gonna be mad but you never know when or why.
Writing TypeScript is basically like trying to use a computer with a bi-polar goat in the room. You’re both gonna be mad but you never know when or why.

The Problem

In a constants.ts file, I had this here:

/** a string that can be used by a RegExp to identify start and ends of sentences */
const punctuations: RegexQuery = "\\.,;:!?‽¡¿⸘()\\[\\]{}<>’'«»…\"\n\t\r";

/** a string that can be used by a RegExp to identify symbols that can separate words */
const wordSeparators: RegexQuery =   '—\\.,;:!?‽¡¿⸘()\\[\\]{}<>«»…"\\s';

export {
  punctuations,
  wordSeparators,
};

Then in a constants.test.js file, I had this:

import { describe, expect, it } from '@jest/globals';
import { punctuations, wordSeparators } from '../../src/constants';

  it("has all the common punctuations", () => {
    expect(punctuations).toEqual(
      "\\.,;:!?‽¡¿⸘()\\[\\]{}<>’'«»…\"\n\t\r"
    );
  });
  it("has common word Separators", () => {
    expect(wordSeparators).toEqual(
      '—\\.,;:!?‽¡¿⸘()\\[\\]{}<>«»…"\\s'
    );
  });

I’m literally asking Jest to tell me the thing that I wrote is the thing that I wrote. This is the easiest green check you could ask for.

Instead, I got…

Missing initializer in const declaration

Instead of everything being awesome, I was looking at this.

Error: Missing initializer in const declaration
“your mom is a missing initializer,” I said to the screen.

But what does it mean?

Now, if you’re wondering what, “missing initializer in const declaration” means, it’s this:

the const declaration is missing an initializer

TypeScript (a dick)

Allow me to provide a slightly more helpful explanation that no one else on the internet seems to want to bother to do:

  1. You made TypeScript mad by either declaring a const without setting a value in it (e.g. const foo = []),
  2. or there’s some sort of parsing error (i.e. lol good luck)
Paceaux (a not-dick)

You could spend hours googling this, wondering what the hell is missing in my code.

Nothing is missing.

Everything is fine here.

I wrote valid code.

The Solution (which is not in the code)

My problem was not with the first definition of the error, which would be the code. It was with #2; the parsing error thing.

My problem was with the configuration of both Jest and Babel

Fixing my Jest configuration

In my jest.config.js file, I added a few extra lines

module.exports = {
  testMatch: [
    '(/test/.*|(\\.|/)(test|spec))\\.[jt]sx?$',
    '**/?(*.)+(spec|test).[tj]s?(x)',
  ],
  transform: {
    '^.+\\.[t|j]sx?$': 'babel-jest',
  },
  preset: 'ts-jest',
  testEnvironment: 'node',
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.json',
    },
  },
};
  • I already had added the preset (ts-jest)
  • I needed a global,
    • which was ts-jest,
    • whose configuration referenced my TypeScript configuration

Fixing my Babel Configuration

Over in my .babelrc file, I needed to add another line:

{
    "presets" : [
        [
            "@babel/preset-env",
            {
                "targets" : {
                    "node" : "14",
                    "browsers" : [
                        "> 1%",
                        "last 2 node versions",
                        "ie > 11"
                    ]
                },
                "useBuiltIns" : "usage",
                "corejs" : 3
            }
        ],
        '@babel/preset-typescript'
    ],
    "sourceType": "module",
    "sourceMap": true
}

I needed a second preset, @babel/preset-typescript.

So why the crappy error message?

Because I created my own fancy type, RegexQuery. Which is a type. And Jest doesn’t type-check the tests as they run. That’s what ts-jest is for.

“Missing initializer in const” still generically means, “you declared the constant wrong somehow, dummy.” Which is a technically true statement until I set a configuration for ts-jest to point to my TypeScript configuration, which then brings in my definitions file, wherein it finds my definition of RegexQuery.

And yeah. Then Babel needs to then know it has to compile for TypeScript. Because ts-jest uses Babel.

<sigh>

I know.

It’s not super obvious from the ts-jest documentation or the Jest documentation that you need to touch both configurations. But you do.

TL;DR

Sure, maybe you wrote your code wrong.

But maybe, just maybe, you wrote the configs wrong.

It’s ok. It’s not your fault. TypeScript is a crazy goat.

3 Comments


  1. Reply

    The current version of Jest / ts-jest, v29, complains about this jest.config.js tweak:

    > ts-jest[ts-jest-transformer] (WARN) Define `ts-jest` config under `globals` is deprecated. Please do
    > transform: {
    > : [‘ts-jest’, { /* ts-jest config goes here in Jest */ }],
    > },


    1. Reply

      oh that is a great find

      thank you, I’ll update my post.


  2. Reply

    Thank you, this saved me a lot of bi-polar goat wrangling.

Leave a Reply

You don't have to register to leave a comment. And your email address won't be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.