Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use strict mode for internal TypeScript #504

Closed
kitsonk opened this issue Aug 10, 2018 · 12 comments · Fixed by #505
Closed

Use strict mode for internal TypeScript #504

kitsonk opened this issue Aug 10, 2018 · 12 comments · Fixed by #505

Comments

@kitsonk
Copy link
Contributor

kitsonk commented Aug 10, 2018

While it maybe too far of a journey at the moment to force strict mode on end users, it is likely a good idea to ensure that the internal Deno TypeScript is as strict as possible. Enabling --strict enables implicitly --noImplicitAny, --noImplicitThis, --alwaysStrict, --strictNullChecks, --strictFunctionTypes and --strictPropertyInitialization.

The biggest "challenge" is that null and undefined are incompatible with strict mode on, and the Deno TypeScript code is semi loose with this concept. The other challenge is a lot of code uses an assertion pattern for checking, instead of code branching. Currently TypeScript does not have a way of allowing this to affect call flow analysis (see: microsoft/TypeScript#8655) or co-dependent fields (see: microsoft/TypeScript#11117), which means that the not null assertion operator (!) has to be used in some cases.

@ry
Copy link
Member

ry commented Aug 10, 2018

Yep, I'm all for it.

@benjamingr
Copy link
Contributor

While it maybe too far of a journey at the moment to force strict mode on end users,

I think Deno should absolutely turn on strict mode for all end users if everyone involved in making Deno agrees that's the right thing to do.

Personally I think it's the right thing to do - I usually turn on strictNullChecks on my code - I think we should do what's right rather than provide a bunch of configuration options.

@ry
Copy link
Member

ry commented Aug 10, 2018

@benjamingr One of the nice things about dynamic languages is the ability to be messy and fast - I want to make sure that deno doesn't negate that feature.

@benjamingr
Copy link
Contributor

@ry can you give me an example where strictNullChecks interferes with prototyping? All it does is not let you implicitly assign undefined or null to other types (like number)

@kitsonk
Copy link
Contributor Author

kitsonk commented Aug 11, 2018

@benjamingr, I beg to differ. There are quite a few use cases that can easily frustrate people who are not familiar with TypeScript. I mentioned two above. Until things like this work out of the box, they will be surprising to users:

declare const foo: Map<string, number>;
if (foo.has("bar")) {
  const value: string = foo.get("bar"); // maybe undefined
}

declare bar: string | undefined;
assert(bar != null);
const value: string = bar; // might be undefined

Both of those impact the internal code of demo, there maybe others. As long as there are valid, common patterns that require the not null assertion (!) then forcing that is a step too far.

Personally I wouldn't be opposed to it being on by default, but I suspect I would lose that argument. It would be nice though if we only allow --strict or loose and not make end users have to understand the nuances.

@benjamingr
Copy link
Contributor

Personally I wouldn't be opposed to it being on by default, but I suspect I would lose that argument.

The part that's concerning me here is that I get the feeling like personally none of us seem to be too opposed to it being on by default (maybe Ryan is?) but we're all concerned about it.

For what it's worth - I would personally be totally fine and unsurprised with the above - but that might be just personal bias being used to strictNullChecks.

When was the last time you ran much code without strictNullChecks in production (or at all)?

I totally get a REPL not running in strict mode though.

@ry
Copy link
Member

ry commented Aug 11, 2018

We have a long time to make this decision before these semantics are locked down. Thanks for the input - I think we need to experiment with it. We’re not quite at the point where we can configure user tsconfig yet.

@ry ry closed this as completed in #505 Aug 15, 2018
@Ciantic
Copy link

Ciantic commented Feb 22, 2019

I'm not sure is this a right place to speak about the user facing strictness, but my opinion is that:

  • .ts files should be as strict as possible (you can do anything with as any trickery still)
  • .js files should be free to do what ever you want.

Point being that if you use TS you probably love the types and the strictness, if you don't you use JS anyway.

@kitsonk
Copy link
Contributor Author

kitsonk commented Feb 22, 2019

@Ciantic current thinking is that strict mode for TypeScript and type checking for JS will both be opt ins for end users via comfiguration.

@rsp
Copy link
Contributor

rsp commented Nov 12, 2019

We have a long time to make this decision before these semantics are locked down.

@ry has there been any decision about it one way or the other?

It would be good to know the plan how to go about it before the 1.0 comes out.

I would argue to use all of the flags posted by @kitsonk here as the default for all code, not only internal, and here is why:

If the loose mode is the default when the API finalizes and people start writing code, it will never be possible to go more strict because it would break existing code.

If the strict mode is the default and it turns out that it causes problems, it can be changed to loose mode without ever breaking any code so there is no risk in trying the strict default, but now is the only time when the strict default can be tried.

If it means rewriting the code that is currently loose about null/undefined then I would like to help, as I would think that having the first runtime that doesn't suffer from The Billion Dollar Mistake would be well worth it.

I would think about type safety in the same way as about security - I would prefer being safe by default and having to explicitly go unsafe than the other way around.

And using TypeScript in a way that doesn't even make this type safe:

const f = (x: string) => x.toLowerCase();

not to mention more complex examples, is not using TypeScript's full potential.

In any case, whether you agree about the usefulness of avoiding Uncaught TypeError: f is not a function and Uncaught TypeError: Cannot read property 'map' of null or not, the fact is that it will always be possible to become less strict if there is a need, not so much for becoming more strict when the loose code is already on the loose, so to speak.

That's why I hope that Deno 1.0 will use strict TypeScript by default.

@kitsonk
Copy link
Contributor Author

kitsonk commented Nov 12, 2019

@rsp I think we should start another issue, which is setting strict as default instead of extending this issue.

@Ciantic
Copy link

Ciantic commented Nov 12, 2019

Okay #3324

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants