Replies: 31 comments 1 reply
-
no need to remove decorators (emitDecoratorMetaData) until they are in stage3. https://slides.com/pzuraq/decorators-a-new-proposal-2020-09. |
Beta Was this translation helpful? Give feedback.
-
Reflect Metadata (which is what 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 |
Beta Was this translation helpful? Give feedback.
-
Yes, I know that it is incompatible. JSX is also not a standard, but you can use
By the way, this will also be a problem for https://github.com/alosaur/alosaur. |
Beta Was this translation helpful? Give feedback.
-
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 I would just not want it to be a flag. |
Beta Was this translation helpful? Give feedback.
-
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 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
I am sure many people out there in the Deno community or the typescript community itself use and require a I am not entirely sure, when |
Beta Was this translation helpful? Give feedback.
-
Since deno 1.4.0, Without a custom 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 |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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 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 Now, this concept was overlooked in the early days of Deno, which (I assume) lead to the introduction of the 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.
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. |
Beta Was this translation helpful? Give feedback.
-
@0kku I think your answer only focused on experimental features, and missed the 75% of my whole point which is all the features Also, as @nktpro mentioned, there never was a need for tsconfig and their application, things changed, and now they are using
@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 |
Beta Was this translation helpful? Give feedback.
-
@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. |
Beta Was this translation helpful? Give feedback.
-
@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. |
Beta Was this translation helpful? Give feedback.
-
@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. |
Beta Was this translation helpful? Give feedback.
-
@Soremwar if something exists and is useful, then it’s useful. That’s the whole point of my argument, if it’s useful then it’s should be kept. The energies of removing it should rather be/may be focused on how to have a workaround. |
Beta Was this translation helpful? Give feedback.
-
@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.
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. |
Beta Was this translation helpful? Give feedback.
-
@andreespirela to be honest, the fact that people need to use a 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 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
@nayeemrmn and @kitsonk Thanks guys for the clarification. I'll attempt to summarize:
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 In order for us to conclude what's the optimal convention to replace |
Beta Was this translation helpful? Give feedback.
-
Not specifically. We want to avoid a proliferation of flags. We would likely introduce it in Other suggestion the core team recently talked about, which I think are worth pursuing are:
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. |
Beta Was this translation helpful? Give feedback.
-
I am strongly in favor of removing The The only issue with this as pointed out above is when new flags are introduced in Let's also look at the alternative (i.e. keeping A third option would be to provide a mandatory baseline for those options we strongly think should be fixed (e.g. |
Beta Was this translation helpful? Give feedback.
-
Questions:
|
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
In short, does this mean |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
@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 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.
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. |
Beta Was this translation helpful? Give feedback.
-
Deno never has, nor never will look at the So I am afraid you argument doesn't make any sense in a Deno context. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Because Deno does not use
|
Beta Was this translation helpful? Give feedback.
-
I don't think it's been mentioned, triple-slash lib 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. |
Beta Was this translation helpful? Give feedback.
-
I know this maybe a niche use case, but can we throw front-end TypeScript code into consideration here too? I have a project (here) that has Deno code and frontend code, all TypeScript, and sharing some common type definitions. At the moment the frontend code is bundled with esbuild, but could potentially be bundled with Deno's built-in SWC instead. Having one tool that can compile, lint, format, and test (though probably not in the case of front-end code), is an incredible feature that Deno excels at. However, Deno types are not compatible with DOM types, and if the option to configure with a tsconfig goes away I will be even more rudderless. An argument for having two separate tools (Deno fmt for B/E code, tsc / eslint for F/E code) is fine, but at the moment that isn't possible to do with VS Code (the most popular editor by far). Using a triple-slash directive to include DOM types is not desirable either, as it's not consistently used, will probably go away, and I don't want to write it in every F/E module. Am I just missing something here? Is there actually a simple solution I'm overlooking? |
Beta Was this translation helpful? Give feedback.
-
However, I think an interesting compromise could be reached with respect to pedantic options if we could do this. I would suggest removing --config to avoid options being specified globally, but allowing files to reference a tsconfig.ts file for use only within the file, possibly in the same format as a compiler directive, thus allowing users to access pedantic options if they wish to use them. I am enormously excited for noUncheckedIndexedAccess, and would hate to see it go away permanently for Deno. I also understand that this might not be possible, or maybe not even worth the effort, as I am not familiar with the Typescript's code, but I still think efforts towards a compromise should be made.
I agree that triple-slash directives being used to set global compiler options is a really bad idea, but I think they could still have a future if this idea of file-wide tsconfigs could be achieved. Edit: Now that I think about it, a similar model could be applied to import maps, to allow different projects to use different import maps. This could bypass a lot of issues in module resolution, and even become Deno's standard for package management. |
Beta Was this translation helpful? Give feedback.
-
TL;DR
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.
Context
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 likeconst 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.
Proposal
We should remove the
--config
option on the command line, disallowing the use of atsconfig.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.).Other Considerations
What can be configured?
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 oftsc
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 hasexperimentalDecorators
(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 supportemitDecoratorMetaData
under Deno (but enableexperimentalDecorators
).jsx
,jsxFactory
,jsxFragmentFactory
- The default forjsx
isreact
, which means that JSX is transpiled into factory functions. For running under Denoreact
is the only sensible option, aspreserve
orreact-native
make no sense. WhilejsxFactory
andjsxFragmentFactory
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 toReact.createElement
.--jsx-fragment-factory
- Sets the factory function for transpiling JSX fragments. Defaults toReact.Fragment
.What about pedantic or linting type options?
tsc
supports (or will be supporting) a few options which impact the type checking. Deno already defaults tostrict
beingtrue
, it will also be enablingisolatedModules
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 ofnoUncheckedIndexedAccess
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).Better documentation of TypeScript under Deno
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.Proposed rollout
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.
Beta Was this translation helpful? Give feedback.
All reactions