In order to have consistent and predictable behaviour of using TypeScript under Deno, we should remove the ability to change the TypeScript configuration in the command line.
As TypeScript has evolved, the configuration of TypeScript has gotten more and more complex. With the design goal to not make major breaking changes against TypeScript 1.0, it has meant that the tsc
TypeScript compiler is carrying a decent amount of _baggage_ with it, supporting a decent amount of legacy code. This has caused challenges to make TypeScript code runnable everywhere.
Even though TypeScript has a design goal to not have type directed emits, a few have leaked into the language over the years. Back when only tsc
transpiled TypeScript this was not a major factor, but as Babel and others have started transpiling TypeScript, this problems came to the forefront. Things like const enum
are not supportable without type information, and the co-mingling of importing and re-exporting runtime code and types through the same statements have made this a challenge.
When we started Deno, we were _ignorant_ of some of these challenges. We were learning about tsc
and TypeScript as a whole along the way. We also felt that we should give people the ability to configure TypeScript under Deno for those options which don't really impact the actual runtime code under Deno. This decision though can make it difficult to run TypeScript under Deno, especially for depending on external libraries and code.
The vision with Deno is that it should be fun and easy to use. If you want to grab a library written for Deno, it isn't so much fun to have to read instructions about what setting you might need to put in a tsconfig.json
and what to run on the command line in order to have your third party dependency work, especially not fun if it is a transitive dependency.
The core team recently had a chat about how having _n_ options for TypeScript makes it difficult to treat TypeScript as a first-class language and can easily "get in the way" which drives people to not want to use it, something we don't really want to see happen.
Also, there was a recent suggest (#7701) to apply a different configuration to dependencies than local code. This demonstrates that people are struggling with this and it is getting in the way. We don't want a situation where you have to jump through hoops to utilise TypeScript code in Deno, setting up multiple configurations, etc. If that means we have to constrain and be opinionated about the way we use TypeScript, so there is one way to write TypeScript to run under Deno, then that is what we have to do, even if that it means we have to _break_ some of the existing TypeScript out there that runs under Deno.
We should remove the --config
option on the command line, disallowing the use of a tsconfig.json
file for running TypeScript code under Deno.
We should clearly document what our settings are for TypeScript compilation that vary from the defaults of tsc
, as well as better document how we treat TypeScript differently than other transpilers/runtimes (e.g. we only use module specifiers with extensions, plus the support of @deno-types
, etc.).
There are a handful of options which effect the emit, which we might need to consider a level of user control, if we cannot agree to what they should be set to:
checkJs
- If the type checking of tsc
should be applied to JavaScript files as well as TypeScript files. This feels though like this could easily be elevated to a top level flag of --check-js
.emitDecoratorMetaData
- Our current transpiling configuration (--no-check
) implicitly has experimentalDecorators
(in fact you can't actually disable it). This requires these decorators, but also emits some limited type information. I know there are some libraries out there that use both these features, but both these features are technical dead-ends. The proposal for ES Decorators is incompatible with these decorators and existing decorators will become _legacy_ decorators and always be transpiled. Any type meta data would need to be re-proposed to TC39 and adopted, meaning that it is super unlikely that current semantics of the meta data will be preserved. While I think we should strongly discourage the use of legacy decorators it does no harm in use enabling the transpilation of them by default. On the other hand, always emitting meta data is an emit and runtime overhead that is not generally used by everyone. My personal feeling is that we would not support emitDecoratorMetaData
under Deno (but enable experimentalDecorators
).jsx
, jsxFactory
, jsxFragmentFactory
- The default for jsx
is react
, which means that JSX is transpiled into factory functions. For running under Deno react
is the only sensible option, as preserve
or react-native
make no sense. While jsxFactory
and jsxFragmentFactory
would still need to be user configurable, as it has a heavy reliance on what sort of SSR might be being done with the code, and I personally believe the other way of setting these (/* @jsx */
) would be insufficient in many use cases. We should consider adding them as flags.So in summary, I am proposing the addition of the following flags/options for CLI:
--check-js
- Type checking would be applied to JavaScript files in addition to TypeScript files. This is incompatible with --no-check
which skips type checking entirely.--jsx-factory
- Sets the factory function for transpiling JSX. Defaults to React.createElement
.--jsx-fragment-factory
- Sets the factory function for transpiling JSX fragments. Defaults to React.Fragment
.tsc
supports (or will be supporting) a few options which impact the type checking. Deno already defaults to strict
being true
, it will also be enabling isolatedModules
by default to ensure that all code is --no-check
_safe_. My opinion is we should take a hard line on these options and say they are not supportable under Deno. Specifically in TypeScript 4.1, there will be the introduction of noUncheckedIndexedAccess
while this can catch quite a few classes of runtime errors or logic error in code, the TypeScript core team makes it clear that they don't think it currently makes a good _sensible default_, as there are many many real world false positives. It is a very good flag where you completely control the code base and have limited type script dependencies (or you are relying only on the type definitions of other JavaScript libraries). None of that is the case with the general use of Deno. We treat TypeScript as a first class language which means the code a developer authors is treated the same as a 3rd party dependency, just as JavaScript, no matter the source, all runs in the same runtime.
Therefore, I feel we have to take a very hard line on what we support. If people want to enforce these pedantic or linting options, it shouldn't be through the Deno CLI (possible would want to consider supporting it under the Deno Language Service though, so people could get design time enforcement, like people can do with --no-check
currently).
We can improve the documentation of TypeScript under Deno, especially give a good explainer of how TypeScript under Deno would differ against the defaults of tsc
, to help those who are already familiar with TypeScript ensure they understand how TypeScript behaves under Deno.
This would be breaking. My opinion is that we try to lock down and document the approach for Deno 1.5 and introduce a warning for those using --config
that it is being deprecated, then with Deno 1.6 we remove the option.
The biggest impact will be on any libraries that utilise --emitDecoratorMetaData
or expect user code to have --emitDecoratorMetaData
enabled. The other breaking change was already in flight around --isolatedModules
.
_But isn't this a big breaking change, what about semver?_ Yeah, maybe, but mostly this is eliminating options that are leading to a fractured user base. Deno is still young, and having some disruption now will result in a better situation in the future, where people can confidently write code, JavaScript or TypeScript that they know will work under Deno without having to do a huge amount of education of the user. All that being said, it is only my personal suggestion at this point, something the core team needs to talk about.
no need to remove decorators (emitDecoratorMetaData) until they are in stage3. https://slides.com/pzuraq/decorators-a-new-proposal-2020-09.
Reflect Metadata (which is what emitDecoratorMetaData
is) is not ES Decorators. It is a seperate concept. The metadata concept that is in the current ES Decorators proposal is totally incompatible with emitDecoratorMetaData
.
To make it clear, I am proposing we keep "legacy" Stage 2 decorators, as supported by TypeScript, though we should actively discourage their use. Basically if you don't use them there is nothing in the emit. I am proposing we disallow emitDecoratorMetaData
because if it is implicitly true, and you use decorators, it will add to the emit, wether you want to or not and it will be adding something that will never make the standard.
Yes, I know that it is incompatible.
But so far there is no definite solution for reflect.metadata with such large libas as Angular and NestJs.
This also means that it will be impossible to use Angular renderer in Deno. https://github.com/alosaur/angular_deno
JSX is also not a standard, but you can use
--jsx-factory- Sets the factory function for transpiling JSX. Defaults to React.createElement.
--jsx-fragment-factory - Sets the factory function for transpiling JSX fragments. Defaults to React.Fragment.
By the way, this will also be a problem for https://github.com/alosaur/alosaur.
It does seem that the two features are used coupled together. I have personally avoided them all together because I thought they were a mistake adding them early to TypeScript (which appears to be proven out). Since experimentalDecorators
would be explicit, and you are already making a decision to use them if they appear in the code, then having emiteDecoratorMetaData
being implicit I guess would be fine as well. We are 6 months at least away from a Stage 3 proposal, so we can figure out how to migrate from there.
I would just not want it to be a flag.
I'd like to give some of my thoughts in this discussion. I will go straight to the point: I don't think this should be done (not only personally speaking, but most importantly, professionally speaking). Personally speaking, the whole ecosystem of Mandarine needs an specific tsconfig.json
file in order to work, could this have been different? By all means, but it was not the way I coded it, and now there are people relying on Mandarine and so personally speaking as someone part of the Deno community, it does have a negative effect on several projects I have worked on in Deno for Deno.
Professionally speaking, I would like to not only mention Mandarine's case but to mention the needs of the community. The fact that we are allowed to use tsconfig.json
by TSC
and sure by any other transpiler is not because having a configuration looks fancy but rather because there is a business need for this (and there will be), tsconfig.json
is not going anywhere, it will be used and more flags will be added to it, and thus, at some point I would argue:
1) Many people will need one or other flag from it.
2) The very fact of treating typescript as a "first class language" in Deno, means it should support every feature typescript has, that would include the feature of having the option to personalize the behavior of the compiler through tsconfig.json
.
3) Large projects in Large companies often require a "access door" to configurations in order to enable/disable features that have or will affect the application in known or unknown ways. This "access door" would be tsconfig.json
which is of course, highly used in enterprise applications based on Angular or NestJS, but not to mention private applications where many companies also use tsconfig.json
for their internal behaviors.
- Using tsconfig.json
in this context isn't about configuration but adaptability & enterprise needs. (Kind of what has been commented by @irustm)
I am sure many people out there in the Deno community or the typescript community itself use and require a tsconfig.json
for several scenarios, I, myself, find it necessary for several of my projects, without it, I feel forced to have certain paradigms or coding styles I am just not comfortable with. A total different scenario would be if tsc
would remove it, but as long as tsc
supports it, I think it's worth supporting it not only from a developer standpoint but from honoring all the features of the original compiler.
I am not entirely sure, when --config
was introduced in Deno but it's been a long way since then, we are almost in version 1.5.0 and it's still there, what I am essentially saying is that there are for sure, many applications that require such configuration file & while there is a need, it should be supported. Whether there can be internal problems in the Deno core with tsconfig.json
or not is something I don't know or whether tsconfig.json
makes things difficult internally... but if that is the case, the workaround should not be removing it rather than figuring out different paths to keep working with it.
Since deno 1.4.0, "importsNotUsedAsValues": "error"
was enabled by default, which basically broke all of our existing projects. The only viable escape hatch was to override this back to "importsNotUsedAsValues": "remove"
using a custom tsconfig.json
(we never needed one before that). Even if we could have spent all the efforts to urgently migrate our own code, it's impossible to have all projects successfully compiled again without all third-party dependencies to migrate as well, which is simply not realistic.
Without a custom tsconfig.json
escape hatch, this could have been a massive disaster of a deno release. As such, I just want to add this as a hard real-world data-point here to take into consideration before dropping support of custom tsconfig.json
.
It's reasonable to expect future deno releases to make breaking changes by changing its default tsconfig internally. What's not ok is leaving the users absolutely no choice to gradually migrate. Currently, a custom tsconfig.json
is the only known way to do so.
So, let me get this straight @andreespirela... You put your "professional business needs" in the hands of an experimental feature we've known for a couple years now will _never_ become a standard part of the language; and now you're upset that when people are unwilling to bear the burden of dead-end legacy features in their runtimes, your library built around volatile experimental features might break? 馃槙 Not trying to be rude, but it seems to me like you were asking for it. Putting experimental features into production is always a gamble, and never one I'd personally be willing to take.
Type-driven emits and non-standard runtime features are a hinderance on the future evolution of TS and not something Deno should waste their time on imo.
I wanna share my thoughts about this as well.
First of all, TypeScript is not a conventional language, it was designed to deal with the issues that development with JavaScript caused to some developers. That said, it's clear that is not meant to be used as a standalone tool. Every method that uses TypeScript to achieve it's execution requires transpilation to JavaScript, and the same could be said about it's distribution method, that is exactly _the issue with allowing a custom configuration file for TypeScript in the first place_.
Libraries written in TypeScript published on NPM use methods of transpilation to achieve it's usability across all Node ecosystem, so they don't have to deal at any point with these kind of issues. In fact, deno.land/x and nest.land are quite probably the only examples of TypeScript code meant to be used __directly__ by the users.
What does this mean to users? Practical example that has sadly caused problems by early adopters of Deno for frontend activities.
_I use a library A that uses the DOM APIs to accomplish a task, so it tells me in their README that I should a tsconfig just like the one that is provided in the repository, including the {lib: "DOM"}
option included with it. However, since I'm using the Deno apis inside my project, I must also include the "deno.ns" library inside the lib option cause I already replaced the default for this option by changing it._
This has been disruptive for many users, since it was not documented clearly back in the day (not sure about now). However it reflects a situation that should be clear to some by now: __The TypeScript implementation inside Deno is not the same that can be seen in Node__. The developers of Deno have changed, adjusted and thinkered with many options in order to make it work the way it is today, to the point that moving configuration inside tsconfig.json
will have unexpected behaviors that are not expected by Node TypeScript users. ES modules, URL resolution, import maps and more are proof of this.
Now, this concept was overlooked in the early days of Deno, which (I assume) lead to the introduction of the --config
option, but caused many early adopters to assume the results would be the same as in the Node implementation. As an example, some library authors disable or enable strict checks for developing their tools, and then require users to use tsconfig.json
to adjust to their codebase structure. This is gonna scalate quickly into a mess if it's not regulated. If not, soon cases will be seen when the use of two different libraries in a same project is not possible cause one of them has a set of rules that conflict with the structure of the other (I'm confident that this has already happen at least once).
And last but not less important, a compiled language should NOT have configuration that allow people to decide what is acceptable and what not in the syntax of the code. ts-ignore
and all the sets of rules aren't meant to be used as a way to skip the expected syntax of the code, but to help TypeScript when it's deduction isn't enough to understand what the user is trying to tell.
Without it, I feel forced to have certain paradigms or coding styles I am just not comfortable with.
The issue with coding styles should not be left to decission of a compiler, but rather the linter embedded in Deno.
That said, there are two possible ways to deal with the problems presented by this inconsistencies in the codebase.
1 - Config file is removed all together by 2.0 and library authors adjust their code to work with future versions of Deno.
2 - Library authors with specific rules must bundle their code before release so it can be used uniformally by the users. In this case, quite possibly the only justifiable rules to keep inside a tsconfig.json for users might be the lib
configuration.
@0kku I think your answer only focused on experimental features, and missed the 75% of my whole point which is all the features tsconfig
offers for configuration, and the business needs it has in a global context, if we measure how many applications use tsconfig
in the world, I am sure the result would be huge and I think we can both agree on that.
Also, as @nktpro mentioned, there never was a need for tsconfig and their application, things changed, and now they are using tsconfig
in order to keep their application compatible with Deno. Nothing assures things won't change in the future, and more breaking features that can be "non-breaking" under certain flags will come along the way.
1) The amount of effort to adapt an application from a tsconfig-driven
to a non tsconfig-driven
will be huge as @nktpro also pointed out.
@0kku again, my whole point is not about whether we want to support experimental features or not, my whole point is about If Deno uses Typescript and Typescript comes with the option to configure the transpiler through tsconfig.json
then by all means we should keep supporting tsconfig.json
, not only because it is part of Typescript, but also because from a global perspective, the needs of a tsconfig.json
is massive in the community, you can see that in the NodeJS community with frameworks such as Angular or NestJS, and I am sure many others, and as the Deno community keeps growing, it will also be massively needed here too. You can't really assume people will just not need it just because, there is always going to be someone who will need it, there is always going to be an enterprise that will need it, there is always going to be a huge and large project that will require a tsconfig.json
, whatever reason? we shouldn't care, we should only care about the point that it's needed and it will be needed
Without a custom
tsconfig.json
escape hatch, this could have been a massive disaster of a deno release. As such, I just want to add this as a hard real-world data-point here to take into consideration before dropping support of customtsconfig.json
.
@nktpro The existence of the escape hatch was taken into account when that change was made. The same trade-offs will be taken into account for future changes given the options that are available then.
We're not going to keep changing the internal tsconfig, we're getting this stuff out of the way while Deno is still young. Removing the external config is a big step towards unifying TS's effect on user code and will only lead to more stability.
@andreespirela People using something that exists is no proof that it's fundamentally needed.
@nayeemrmn That's debatable as I can argue if something exists and something is used is definitely because it's needed, on the other hand if something exists but it's not used, then it's not needed (and we can be sure about it 100%) but not the other way around.
@andreespirela Or if something exists and is useful but causes more problems than what it actually solves, is it worth having?
As I pointed out above, Node simply jumps over this problems, but Deno can't.
@Soremwar if something exists and is useful, then it鈥檚 useful. That鈥檚 the whole point of my argument, if it鈥檚 useful then it鈥檚 should be kept. The energies of removing it should rather be/may be focused on how to have a workaround.
@andreespirela What is exactly the work-around here? Having different set of configurations for code that is going to be compiled all together isn't something conciliable.
Removing the external config is a big step towards unifying TS's effect on user code and will only lead to more stability.
Quote of the year
Tsconfig is a complete design mistake in my opinion. Being a different implementation, Deno shouldn't have to cope with the problems it brings.
@andreespirela to be honest, the fact that people need to use a tsconfig.json
to run some projects is _exactly_ why we need to change this. I wish I had been forceful earlier on, I didn't think it was a big deal allowing _n_ versions of TypeScript to be run with Deno, because _hey that is what tsc
does_. Testament that people have to instruct users to --config tsconfig.json
to use their software is a barrier to entry, and it is possible/highly likely that some settings in --config tsconfig.json
could then break other libraries, and the only thing people will do is blame Deno.
This is why we have close the gate, after the horse has bolted, I admit, but while things don't get worse. I am afraid your arguments have only increased my desire to make this happen.
@nktpro while I realise it was/is disruptive, this again is support for doing this. We need to break code, so that your libraries can run safely under --no-check
as well as with full type checking. There are huge benefits to everyone to have code reliably work under --no-check
. If we have a breaking config change post this, we can always consider a single flag escape hatch for a period of time to allow people to adjust. Hopefully though we have matured enough with our TypeScript usage in Deno that future breaking changes will be TypeScript language breaking changes, but giving people a predictable and stable way to write TypeScript for Deno helps everyone be more productive.
As someone watching from the sidelines, arguments like "X project already uses it" or even "Y environments often rely on it" seem very weak. Supporting features because people use them is a great way to get bogged down with terrible design decisions. See C's support for implicit declarations and implicitly typing things as int
for decades, Haskell's default string type still being a linked list because that's what was easy (among many other decisions generally seen as mistakes as Haskell's scope grew), or Rust's backwards compatibility meaning Vec::remove
still panics when the provided index is invalid, with no fallible alternative. See most of the things considered bad style in Javascript.
These mistakes are so long-lived because they weren't phased out in time to avoid enormous stability problems. Deno still has time to fix problems, right now, and it seems obvious to me that it should do everything it can to do so.
Is --config
a design mistake that Deno needs to deal with? It certainly seems like it is to me, in its current form. The way configuration of Typescript works is fundamentally incompatible with how Deno works. If a different method of configuration could be introduced that somehow respected module/library boundaries better, it would be a different story. --config
as it stands doesn't appear to be worth the problems it has the potential to create, regardless of who already use it. Problems that it solves need better solutions, more suited to the way Deno operates.
Sound as you need to remove all the flags so that there are no incompatibilities in future versions.
I suggest you remove all the flags then. That would be fair then. Otherwise, it sounds like Deno is able to devote time to support only 3 flags. :(
--check-js
--jsx-factory
--jsx-fragment-factory
@nayeemrmn and @kitsonk Thanks guys for the clarification. I'll attempt to summarize:
deno
users currently rely on custom tsconfig.json
files for different reasons. One key reason is maintaining backwards compatibility for existing applications, and deno
contributors are fully aware of that escape hatch."importsNotUsedAsValues": "error"
breaking change, we'll need to add an equivalent CLI flag for it (e.g --imports-not-used-as-values
) before --config
support can be removed.deno
's internal default tsconfig, new corresponding flags should be added to provide backwards compatibility. Of course we can't expect all those backwards-compat flags to be supported forever. As always in software development, we just need a migration path and a reasonable migration period.
With backwards compatibility aspect being addressed and out of the way, I agree removing --config
is a better path for deno
and its users are better off without it in the long run. tsconfig.json
as it stands today provides way too much configuration surface area. That amount of flexibility comes with a lot of headaches for both deno
contributors and its users ("with great power comes great responsibility"). Convention over configuration has been a deno
's key strength and philosophy to help us arrive at the "it just works" holy grail (or at least very close to that, in practice).
In order for us to conclude what's the optimal convention to replace --config
, let's continue to hear more about other specific real-world use cases today where users have to resort to --config
outside of backwards compatibility.
- Specifically for the case of
"importsNotUsedAsValues": "error"
breaking change, we'll need to add an equivalent CLI flag for it (e.g--imports-not-used-as-values
) before--config
support can be removed.
Not specifically. We want to avoid a proliferation of flags. We would likely introduce it in --unstable
for a minor release (like we have for "importsNotUsedAsValue"
) to reduce the impact. We might want to consider a --legacy
flag as a final escape hatch, but we need to push people to update their code, as it benefits no one to have to use configuration or flags to be able to run code. Especially with "importsNotUsedAsValue"
and "isolatedModules"
this is to _force_ everyone to write their TypeScript in a way that it can be transpiled without type checking. Being able to opt out of type checking but still run TypeScript code under Deno benefits everyone.
Other suggestion the core team recently talked about, which I think are worth pursuing are:
deno run
, potentially introduce something like deno check
which would do a type check of the code.Both of these would significantly reduce the "pain" of just getting something to run under Deno so you can try to figure out how to improve it or fix issues.
I am strongly in favor of removing --config
, otherwise it will be a nightmare to get different libraries working together in the future (as it already is now). If TypeScript is meant to be a first-class citizen for writing apps with Deno, we need to treat it more like other statically typed compiled languages like Java and C#, which do not allow opting out of compiler features, but still allow enforcing certain coding styles/language construct usages via linters/analyzers.
The tsconfig.json
settings used by Deno should provide a sensible baseline that makes all code compatible while linters can then run only on app code and ignore lib code (which TypeScript cannot do unless libraries are pre-compiled/pre-bundled). We are also in the fortunate situation that TypeScript is rather mature by now, so we do not need to go through the same "growing pains" TypeScript had, which lead to many of those flags being introduced (in addition to having to support multiple runtimes, i.e. Node and browsers). We can choose a sensible baseline of compiler settings as of TypeScript 4.0 and call it "Deno TypeScript".
The only issue with this as pointed out above is when new flags are introduced in tsc
, which may represent a breaking change based on the value Deno chooses as a baseline. There are many pros and cons to be found in maintaining backwards compatibility (many people attribute Java's success to its backwards compatibility), but each of these cases needs to be looked at separately to make a sensible decision in the future. It probably makes sense to strive for maximum backwards compatibility with the occasional breaking change.
Let's also look at the alternative (i.e. keeping --config
) and how that could work. If we use Java and C# as examples again, we see that libraries are not distributed as code (i.e. TypeScript for Deno), but instead as compiled bytecode (i.e. JavaScript for Deno) which still carries type information (i.e. .d.ts
files for Deno). If we take the same mindset that means libraries have to be distributed pre-compiled and we have to use --skipLibCheck
to allow libraries to use different compiler options than the apps using them. This will make authoring libraries slightly more cumbersome but allows for flexibility in choosing compiler options, since libraries and apps can each have their own tsconfig.json
.
A third option would be to provide a mandatory baseline for those options we strongly think should be fixed (e.g. --strict
comes to mind since it is already a default today) and to expose those compiler flags that are more use-case driven (e.g. for decorators).
Questions:
Eventually, if TS introduces a new aspect to strict
for example noUncheckedIndexedAccess
gets added to strict, in TS 4.X, it could break every project out there. Almost every TS update, has some breaking change in there as it does not follow SemVer. If Deno is following SemVer, will Deno not become a breaking change every time it updates TS and need to bump major? Or is Deno shedding SemVer similar to TS?
How would other options besides compiler options be able to be used? For example, the includes
option? The includes options allows typing augmentation to work properly.
Personally, I have no problem with writing super strict code, and I find that code written in a hyper strict way is the safest code that one can get their hands on.
The Rust compiler's defaults are very strict, and I love it, so I don't really need to change anything when writing Rust.
C++ compilers are not strict at all, actually, they're laughable unstrict, allowing weird, unsafe code to pass without even issuing a warning! So I make sure to bring my own finely tuned configuration to every C++ project I run.
TypeScript suffers from the same problem as C++ does, so I make sure to enable the strictest subset of TS possible.
But... TS's configuration is only possible through "tsconfig.json" files.
Deno's default is pretty good, but I'm one of those people who really want to get their hands on TS's "noUncheckedIndexedAccess," so you can get where I'm coming from.
At a minimum, a "pedantic" flag would be a must.
Also, a faster TSC would be nice, if Deno were to cut out a large amount of the old code that is bogging down TSC and bundle it with Deno, I am confident that many of Deno's users would appreciate the smaller binary sizes and improved performance.
(there might be a few who wanted their Deno binary to be large and their code to compile slowely, but they are likely to be a minority)
In short, does this mean tsconfig.json
won't be allowed, thus things like decorators just can't be used for deno projects?
In short, does this mean
tsconfig.json
won't be allowed, thus things like decorators just can't be used for deno projects?
As per discussions with @kitsonk , @lucacasonato & @bartlomieju on the Discord chat, it seems like it will be enabled by default (decorators & metadata), but they will be removed when the official TS39 decorators come out. It's yet to be fully addressed afaik.
cc @ebebbington
@kitsonk Sorry to bother you, before --config is removed, I was wondering about the effects of applying --config to all code(including deps) beyond the compiler options. I believe removing --config also breaks TypeScript Module Augmentation, since --config is necessary for this no because without the includes
module augmentation doesnt work the same. So if we remove the config option, we lose the ability to do module augmentation. But if we keep it, it's still broken because the augmented module typings are now applied to all code(including deps.)
When u run this
When u import it,it will not use it
And when u do run it like this the internal libraries/deps break cause they don't work the same since the same rules are applied on all including lib code
Module augmentation is way too useful a feature to disable for all users.
Inclusion of a file can be accomplished in 3 ways:
- with a tsconfig, telling it where to look via "include" , "exclude", and "files" arrays
- via an import
- via a /// <reference>
The second and third are possible but when you have to use it in 100s of files, having to import files or declare /// isn't really clean and also causes a much worse dev experience.
I believe removing
--config
also breaks TypeScript Module Augmentation, since--config
is necessary for this no because without the includes module augmentation doesnt work the same.
Deno never has, nor never will look at the includes
in a tsconfig.json
file. It is never passed to the TypeScript compiler. Deno modules resolution is a little bit complex, and I am working on documentation to clarify it, but if it isn't seen with deno info
, it isn't part of the program that is considered for TypeChecking (there is a slight caveat that current implementation of info
does not include some of the type only dependencies, which will be fixed for 1.6).
So I am afraid you argument doesn't make any sense in a Deno context.
After further testing you are right the --config tsconfig.json has no effect but this was the issue I was referring to:
tsconfig.json
Once i delete the tsconfig.json
But these are declared!
Add the tsconfig.json back and the errors disappear! Includes is definitely doing something in VSC side so maybe this is an issue for vscode_deno. 馃
Without includes working module augmentation is still not working. Out of curiosity why is includes ignored by deno? Without it I have to be forced to use --no-check or is this some alternative deno solution I can use?
Out of curiosity why is includes ignored by deno?
Because Deno does not use tsc
for module resolution at all, never has. It builds a graph of your dependencies, and that is what is type checked, "includes"
is somewhat analogous to the modules you pass on the command line via deno run
or deno cache
.
deno info
gives you (mostly) the view Deno has of the code with the caveat I mentioned above.
I don't think it's been mentioned, triple-slash directives need to go away along with this. They are also a way to configure certain compile options globally. Emphasis on "globally" -- you might mistake their behaviour to be something modular since they're inlined in modules, but in fact they're all just preprocessed before compilation and squished onto the global config. We obviously can't continue to support that.
Most helpful comment
I'd like to give some of my thoughts in this discussion. I will go straight to the point: I don't think this should be done (not only personally speaking, but most importantly, professionally speaking). Personally speaking, the whole ecosystem of Mandarine needs an specific
tsconfig.json
file in order to work, could this have been different? By all means, but it was not the way I coded it, and now there are people relying on Mandarine and so personally speaking as someone part of the Deno community, it does have a negative effect on several projects I have worked on in Deno for Deno.Professionally speaking, I would like to not only mention Mandarine's case but to mention the needs of the community. The fact that we are allowed to use
tsconfig.json
byTSC
and sure by any other transpiler is not because having a configuration looks fancy but rather because there is a business need for this (and there will be),tsconfig.json
is not going anywhere, it will be used and more flags will be added to it, and thus, at some point I would argue:1) Many people will need one or other flag from it.
2) The very fact of treating typescript as a "first class language" in Deno, means it should support every feature typescript has, that would include the feature of having the option to personalize the behavior of the compiler through
tsconfig.json
.3) Large projects in Large companies often require a "access door" to configurations in order to enable/disable features that have or will affect the application in known or unknown ways. This "access door" would be
tsconfig.json
which is of course, highly used in enterprise applications based on Angular or NestJS, but not to mention private applications where many companies also usetsconfig.json
for their internal behaviors.- Using
tsconfig.json
in this context isn't about configuration but adaptability & enterprise needs. (Kind of what has been commented by @irustm)I am sure many people out there in the Deno community or the typescript community itself use and require a
tsconfig.json
for several scenarios, I, myself, find it necessary for several of my projects, without it, I feel forced to have certain paradigms or coding styles I am just not comfortable with. A total different scenario would be iftsc
would remove it, but as long astsc
supports it, I think it's worth supporting it not only from a developer standpoint but from honoring all the features of the original compiler.I am not entirely sure, when
--config
was introduced in Deno but it's been a long way since then, we are almost in version 1.5.0 and it's still there, what I am essentially saying is that there are for sure, many applications that require such configuration file & while there is a need, it should be supported. Whether there can be internal problems in the Deno core withtsconfig.json
or not is something I don't know or whethertsconfig.json
makes things difficult internally... but if that is the case, the workaround should not be removing it rather than figuring out different paths to keep working with it.