Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declare all elements of the webpack.Configuration tree as accepting Readonly<T> #19

Open
cefn opened this issue Mar 8, 2025 · 1 comment

Comments

@cefn
Copy link

cefn commented Mar 8, 2025

Feature request

Typings for webpack configuration objects should be declared as readonly, to align with fundamental behaviours of typescript.

What is the expected behavior?

Typings should allow arrays and objects declared as const for correct type inference and simple declaration of const values by wrapping the whole configuration in a single as const.

What is motivation or use case for adding/changing the behavior?

For example using the configuration below is currently a compiler error...

const webpackOptions = {
  resolve: {
    fallback: {
      zlib: false,
    }
  }
 }

This is because in typescript, mutable types broaden to include all possible values within the type like...

{
  zlib:false
}
// { zlib:boolean }

...whilst declaring the values as const (readonly) infers the literal type of the value.

{
  zlib:false
} as const
// { zlib:false }

Since true is an invalid value for a member of resolve.fallback, then forcing people to use mutable types (without as const) actually creates compiler errors. The error from NOT defining this object within as const looks like...

Property '"zlib"' is incompatible with index signature.
  Type 'boolean' is not assignable to type 'string | false | string[]'.ts(2322)

Workaround

A workaround is to selectively intercept parts of the webpack config which correspond to properly declared types that allow readonly. For example in this case the fallback object has a suitable declaration, so it can be declared as const

const webpackOptions = {
  resolve: {
    fallback: {
      zlib: false,
    } as const
  }
 }

Preferred Solution

Selectively intercepting individual fields for as const inference in this way of course very complex to reason about and solve for in a large webpack config. It's much preferred to allow the following...

const webpackOptions = {
  resolve: {
    fallback: {
      zlib: false,
    }
  }
 } as const

However, this approach is currently defeated by the occasional mutable type declarations in webpack.Configuration. Adding an element declared as a mutable object or array type (that don't accept readonly) fails...

const webpackOptions = {
  resolve: {
    fallback: {
      zlib: false,
    },
  }
  module: {
    rules: [
      {
        test: /\.wasm$/,
        type: "asset/resource",
      },
    ],
  },
 } as const

/* Error  The types of 'module.rules' are incompatible between these types.
* The type 'readonly [{ readonly test: RegExp; readonly type: "asset/resource"; }]' is 'readonly' and cannot be * assigned to the mutable type '(false | "" | 0 | RuleSetRule | "..." | null | undefined)[]' */

Consistently declaring all webpack config as accepting readonly values would solve for the general case.

How should this be implemented in your opinion?

Consistently add Readonly<> around declarations of Configuration structures.

Are you willing to work on this yourself?

Potentially although I don't know the structure of the project.

@alexander-akait alexander-akait transferred this issue from webpack/webpack Mar 10, 2025
@alexander-akait
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants