Skip to content

Tinypool options.env type doesn't accept process.env or SHARE_ENV #136

Open

Description

@slorber

Hi

I don't know if it's a purposeful design decision, but I was surprised that Tinypool's option.env type (Record<string,string>) doesn't match with Node.js Worker(,{env}) type.

It seems that by default Tinypool will have the same behavior and forward the env to workers.

https://nodejs.org/api/worker_threads.html#new-workerfilename-options

env
If set, specifies the initial value of process.env inside the Worker thread. As a special value, worker.SHARE_ENV may be used to specify that the parent thread and the child thread should share their environment variables; in that case, changes to one thread's process.env object affect the other thread as well. Default: process.env.


However, it's not possible to pass process.env or the SHARE_ENV symbol that Worker(,{env}) accepts, and that seems like a type bug?

import {SHARE_ENV, Worker} from 'node:worker_threads';

// Works
      new Worker('', {
        env: process.env,
      });
      new Worker('', {
        env: SHARE_ENV,
      });

// Does not type-check
      new Tinypool({
        env: process.env,
      });
      new Tinypool({
        env: SHARE_ENV,
      });

Is there a good reason to restrict the TypeScript type?

As far as I understand, it should be possible to accept env: process.env or env: {...process.env}

However, due to the Worker/child_process abstraction, supporting SHARE_ENV might not always be possible.

// works
child_process.spawn('', {env: process.env});
// does not work
child_process.spawn('', {env: SHARE_ENV});

Note, the types are not significantly different, just turning it to Record<string, string | undefined> is enough to match process.env

Temporary workaround:

      const env: Record<string, string> = Object.fromEntries(
        Object.entries(process.env).filter(
          (entry): entry is [string, string] => {
            return entry[1] !== undefined;
          },
        ),
      );

Activity

  1. AriPerkkio commented on Sep 4, 2026

    @AriPerkkio
    Member

    No reason, PR welcome.

  2. slorber commented on Sep 4, 2026

    @slorber
    Author

    Hmmm, after double-checking, maybe it's better to keep a narrower type? 🤷‍♂️

    const { Worker } = require("node:worker_threads");
    
    new Worker(
      "console.log(typeof process.env.FOO, JSON.stringify(process.env.FOO))",
      { eval: true, env: { FOO: undefined } },
    );
    
    // > string "undefined"

    The undefined types get transformed to the "undefined" string.

    Although not convenient for env forwarding, the narrower type can also prevent misuse 🤷‍♂️
    Both possible types have pros and cons 😅


    As far as I understand, process.env values are always strings.

    Image

    It looks like the Node type had to use string | undefined to indicate that some accessed env keys might not be set. NOT that a key is set with an undefined value.

    Otherwise, it would require TS users to use noUncheckedIndexedAccess to get string | undefined, which is not the default.

    https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess

    Image

    I don't know how this situation should be handled. Maybe it's Node's responsibility to improve its type, not this library.

    In the meantime, I'll just use process.env as Record<string,string>, that seems like a good-enough workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions