README mentions adding a tsconfig.json, but doesn't say what to put in it
If I add a tsconfig.json, I need to put roughly the following in it:
{
"compilerOptions": {
"strict": true,
"lib": ["DOM", "DOM.Iterable", "ES6"],
"esModuleInterop": true,
"resolveJsonModule": true
},
"exclude": ["node_modules", "dist"],
"include": [".marko-run/routes.d.ts", "src"]
}
If I omit "lib", I'll get TS errors telling me that Promise isn't defined. (You can use something more aggressive than ES2019 if you're targeting modern browsers, but ES6 happens to be the minimum for Promise.)
If I omit either "esModuleInterop" or "resolveJsonModule", I see type errors in the example project, because the file generated in .marko-run/routes.d.ts isn't parsed by typescript, so none of my per-route types seem to be visible in VS Code.
I'm going to suggest adding an example tsconfig.json file?
edit: I thought these were needed but they actually aren't:
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
Good, point we should provide more guidance here. I played around with different configs and this is the minimal I found:
{
"include": ["src/**/*", ".marko-run/*"]
"compilerOptions": {
"strict": true,
"target": "es6",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
}
}
Top-level
-
include - By default TS won't match files/directories starting with
.so adding ".marko-run/*" is necessary. If you are using VSCode with the Marko plugin, it will automatically pull in this file and make the TS defaultincludegenerally good enough. -
exclude - This option filters out files from those matched by
include, so as long as your don't match anything you don't want, you can omit this option.
Compiler Options
-
strict: true - This should always be set to
truewhen using TS! 🙃 -
target: "es6" - Like you said, this is the minimum target for Promise and async (ES5+). This also causes
moduleto be set as "es6" istead of "commonjs" which we want. -
moduleResolution: "node" - By default this is "classic" unless you set
moduleto "nodenext" or "node16" but those values cause other issues. My reading of TS's docs suggest settingmoduleto "esnext" will set this to "node" but that is not what I observe happening. Explicitly setting this seems to be the most reliable. -
allowSyntheticDefaultImports: true - This is necessary to import default
@marko/runas a namespace in the.marko-run/routes.d.tsfile. I think I could actually change that to us a*import instead and this option won't be necessay. Note: settingesModuleInteropto true will also enable this option so that would work too. - resolveJsonModule: true - This is only necessary if you have +meta.json files
Let me know if these work for you and I will update the examples so they don't use the base tsconfig.json and make them more stand-alone.
That looks right to me, but maybe put libs: ['dom'] in as well anyway? I'm thinking that as soon as you write any code in practice, you're going to be wanting to use DOM APIs from event handlers.
@rturnq I can confirm that your suggested minimal tsconfig seems to work fine for me, thank you. 👍
I have other issues that might cause tsconfig.json recommendations to be revisited, but I'll file those separately when I get the brain cycles available.