-
Notifications
You must be signed in to change notification settings - Fork 15
Description
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.