Assume I have some JSON file (let's name it template.json
)
{
"myField1": "",
"myField2": ""
}
I also have a kind of generic class
export default GenericClass<T> {
// Creating an empty constuctor with passed type.
// to allow define type automatically.
// This allow us not to manually set generic type for class
// and also allows Webpack to pick up changes.
constructor(template?: T) {}
// ...some fields and methods
get typedField(): T {
return /* something slightly calculated */
}
}
I'm using it like a type in my Typescript project:
import GenericClass from "path/to/GenericClass"
import template from "template.json"
export type TemplateType = typeof template
export default new GenericClass(template)
// we can also write
// export default new GenericClass<TemplateType>()
// but in this case the changes in template.json
// won't be picked up by Webpack.
// However, this does not affects the problem,
// it occurs in both cases.
I'm running the webpack
dev-server, and use it somewhere:
import * as React from "react"
import GenericInstance from "path/to/GenericInstance"
export default MyComponent extends React.Component {
render() {
var { typedField } = GenericInstance
return (
<main>
<p>{typedField.myField1} {/* ok */}</p>
<p>{typedField.myField2} {/* ok */}</p>
</main>
)
}
}
After that I'm adding a new field into my template.json
:
{
"myField1": "",
"myField2": "",
"myField3": ""
}
Saving it. webpack
dev-server picks up this change in template.json
. Allright. One important thing is that autocomplete of VSCode works (it shows this myField3
in list of available fields). Fine.
At this moment, when I'm trying to use myField3
in MyComponent
(like <p>{typedField.myField3}</p>
), awesome-typescript-loader
sends an error during compilation:
Property 'myField3' does not exist on type '{ "myField1": string; "myField2": string; }'
Obviously, awesome-typescript-loader
did not pick up changes in template.json
which is used as type in my GenericClass
.
How can I beat it? After restart of the dev-server it works fine until I make changes in template.json
.
Partial webpack.config.js
, package.json
and tsconfig.json
config = {
rules: {
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader",
exclude: /node_modules/
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
}
}
{
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
"source-map-loader": "^0.2.4",
"typescript": "^3.3.3",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
}
}
{
"compilerOptions": {
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"baseUrl": "src",
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"strict": false,
"sourceMap": true,
"outDir": "dist/",
"jsx": "react",
"traceResolution": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowJs": true,
"declaration": false,
"removeComments": true,
"noLib": false,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true,
"types": [ "node" ],
"lib": ["es6", "dom", "dom.iterable"],
"downlevelIteration": true,
"resolveJsonModule": true,
"typeRoots": [
"./node_modules/@types"
]
},
"include": [
"src/**/*"
]
}
I can confirm that this occurs only with imported *.json. Probably, the problem can be in touch with resolveJsonModule
setting for TypeScript, but not sure. Setting useCache
and usePrecompiledFiles
to false
explicitly for awesome-typescript-loader
in webpack.config.js
does not help. I mean, changed webpack.config.js
now looks like:
{
test: /\.(t|j)sx?$/,
loader: "awesome-typescript-loader",
options: {
useCache: false,
usePrecompiledFiles: false
},
exclude: /node_modules\/(?!superagent)/,
},
This is a bug in awesome-typescript-loader
. As of v5.2.1, here's a quick fix:
// node_modules/awesome-typescript-loader/dist/instance.js
// ln: 214:
- var EXTENSIONS = /\.tsx?$|\.jsx?$/;
+ var EXTENSIONS = /\.tsx?$|\.jsx?|\.json$/;
Apparently the author forget to include .json
extension as a valid target.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With