Typescript: Allow --strict to take a version number

Created on 26 Sep 2017  路  7Comments  路  Source: microsoft/TypeScript

This is mostly from offhand conversations with @wycats, but I needed to finally file this on the issue tracker.

Background

One of the stances that we've taken is that strict opts you into all strictness settings unless users specifically opt out. That way, users can upgrade, and only if they experience breaks do they need to manually turn options off.

This has some benefits of pushing users towards writing safer code and avoiding bugs (and often getting a better experience in general), but users may not want to have their semantics changed under them by an upgrade, or have to look into new options right away.

Proposal

One way we can alleviate this is by allowing users to lock down their strictness settings by version number. For example, right now we are experimenting adding a new --strictFunctionTypes option under the --strict bucket. For users to avoid this, they could write

{
  "compilerOptions": {
    "strict": "2.5"
  }
}

instead of

{
  "compilerOptions": {
    "strict": true,
    "strictFunctionTypes": false
  }
}

Upsides

I think @wycats might do a better job with the benefits.

  • Users could lock down their strictness settings and upgrade (or just allow npm to do its thing) without being as concerned with breaks.

    • This mean existing code with no maintainers has less of a chance of breakage.

Downsides

Here are some concerns I've come up with off the top of my head:

  • Why do we expect users to be able to lock down on a --strict version number than to lock down on major.minor in npm?
  • Is version number allowed to be an actual number (i.e. 2.5) instead of a string (i.e "2.5") in tsconfig.json? Because inevitably, someone will use a number instead of a string and they will be unhappy when it doesn't work.
  • If we don't expect to introduce many more strictness flags, then that may play a part here.
  • Will new options be discoverable to those users? Is that a problem?
Declined Suggestion

Most helpful comment

If you're trying to preemptively say "strict, but no future strict stuff", you can just list all the individual tags currently grouped under "strict", instead of using "strict" directly. The flag even came with the promise, as @gcnew mentioned, that more strictness checks would be added to it in the future... I feel like the version tag is both somewhat redundant and subverts the flag's goal.

All 7 comments

One of the biggest challenges with --strict in general is how to effectively mix and match strict and non-strict declarations. As we have seen with the stricter generic checks, it can have upstream consequences of poorly formed types/code that have downstream user impacts where it is unclear how to resolve it.

For me, the whole purpose of strict is the automatic opt-in for the newest security options. If library authors/users don't want that, then they shouldn't use strict and list the pertinent flags separately in their tsconfigs instead.

If you're trying to preemptively say "strict, but no future strict stuff", you can just list all the individual tags currently grouped under "strict", instead of using "strict" directly. The flag even came with the promise, as @gcnew mentioned, that more strictness checks would be added to it in the future... I feel like the version tag is both somewhat redundant and subverts the flag's goal.

I actually think --strict itself is a bit of a red herring... Up to this point, pretty much everything has been forward compatible and strict compatible for definitions. There have been instances where they haven't been backwards compatible (readonly, keyof, unions, intersections, etc...). The only challenge with strictness and definition files that I am aware of is #18773.

It feels to me like it is a solution looking for a problem. Not only would it have to be in the tsconfig.json, if it is truly going to be compiler compatible, definition files would need to be emitted with the meta data for library sharing. It feels like something that should be tackled if/when something strict is going to be introduced that has significant opt-in issues. I can understand it is a worry not having granular opt in, but is it a rational fear... Our experience (@dojo) has been that once we got mostly to strict, each new release was a straight forward process. In fact the changes from 2.4 to 2.5 so far has been trivial and things we should have typed better in the first place anyways, and nothing to do with strict.

I'm also not a fan. As Daniel pointed out to me when we discussed this yesterday, there's not really an observable difference between "strict": "2.5" in tsconfig.json vs "typescript": "2.5"in package.json other than creating more headaches for us.

This would be confusing. It implies that a given version of the language is potentially aware of both past and future versions.

It would also seem to suggest that the right way to think about new checks is in the context of language versions when in fact there are individual flags for all significant new strictness improvements precisely because they cross cut with other language improvements.

I would argue that if a new --strict check is introduced, and if one subsequently finds themselves wanting to opt out of said check _and_ any further new --strict checks, that the encouraged approach should be to enable all of the desired ones explicitly.

Major points from SBS

  • strict is supposed to be "lightly breaky"
  • What does "2.6" even mean? You have to go read old release notes?

    • Specifying the individual flags works fine and solves that problem

  • We have no way guarantee any specific behavior in the future
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dlaberge picture dlaberge  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

blendsdk picture blendsdk  路  3Comments

weswigham picture weswigham  路  3Comments