microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.14k stars 12.5k forks source link

tsc --init update 2024 #58420

Open RyanCavanaugh opened 6 months ago

RyanCavanaugh commented 6 months ago

Acknowledgement

Comment

Following up from #58417

Note: This is only for argumentless tsc --init. We know that it's physically possible to write text after --init and that text could do something, but that's a separate issue. Since tsc --init should do something, this issue is only about what that something is.

General consensus from the design meeting + external discussion:

Other live issues:

Other things we didn't get to:

Proposed new output:

{
    // For more info, see https://aka.ms/tsconfig
    // Or use the tsc-init wizard: https://aka.ms/tsc-init
    "compilerOptions": {
        "target": "es2022",
        "module": "nodenext",
        "rootDir": "./src",
        "outDir": "./dist",

        // For nodejs, add "node" to this array,
        // and remove "dom" from "lib"
        "types": [],
        "lib": ["dom", "es2022"],

        // Other outputs
        "sourceMap": true,
        // "declaration: true,

        // Typechecking options
        "noUncheckedIndexedAccess": true,
        "exactOptionalPropertyTypes": true,

        // Style options
        // "noImplicitReturns": true,
        // "noImplicitOverride": true,
        // "noUnusedLocals": true,
        // "noUnusedParameters": true,
        // "noFallthroughCasesInSwitch": true,
        // "noPropertyAccessFromIndexSignature": true,

        // We recommend all of these options
        "verbatimModuleSyntax": true,
        "isolatedModules": true,
        "moduleDetection": "force",
        "skipLibCheck": true,
        "strict": true
    }
}

I tried to order this from "most likely to edit" to "least likely to edit"

andrewbranch commented 6 months ago

Module options look good to me for Node.js / library authoring. I assume you’ve intentionally left in some redundancies so that good option A stays set if someone changes/removes option B that’s currently making A redundant. For good measure, a list of those:

The one that’s missing from this good-but-redundant category is --module nodenext implies --esModuleInterop, which is a good idea to keep on, but the thing people are likely to switch to is --moduleResolution bundler, which implies --allowSyntheticDefaultImports, which is close enough. So not critical to add, I think.

TLDR looks good 👍

DanielRosenwasser commented 6 months ago

Though originally I was thinking more about include over rootDir, it makes sense given the guardrails rootDir provides if you screw something up? And that's important given people try to do custom exclude/include rules that are often unnecessary.

So I'm generally in favor around outDir and rootDir. The thing I am curious about is if we can detect sensible conventions such as folder name and existence of a package.json. This includes stuff like src as a well-known input directory, and special casing depending on if you're running from inside src.

RyanCavanaugh commented 6 months ago

👍 / 👎 ?

        // Other outputs
        // "declaration": true,
        // "sourceMap": true,
andrewbranch commented 6 months ago

Pretty much everybody is going to debug at some point, and it’s going to be bad until they realize they need to enable sourceMap

fatcerberus commented 6 months ago

The only thing that sucks about having options commented out is you can't hover on them to see the description of what they do, which doesn't help when you don't know what something does and want to know if you should enable it. Unfortunately most options don't have an explicit setting that means "use the default behavior, whatever it happens to be today", so no easy solutions to be found here.

Conaclos commented 6 months ago

I could also suggest turning off allowUnreachableCode. It greatly help in some circumstance.

System233 commented 1 month ago

My suggestion is that the tsconfig should only configure basic type checking and avoid trying to add things that users may need. Developers will refer to the documentation to configure what they really need; there's no need to overcomplicate things.

In China, there’s an idiom called “画蛇添足,” which literally means adding feet to a snake while drawing it. This idiom refers to the act of making unnecessary additions that complicate things rather than enhancing them. Adding a lot of options and comments that no one knows who will use or when they will be used exemplifies this unnecessary complication. Attempting to predict developers' environments to generate targeted default configurations and comments will never satisfy everyone. Since that’s the case, why not keep things a little simpler? Therefore, only the most basic configurations should be added, representing the minimal TS/JavaScript development environment. As for what specific options developers actually need, that’s not something we should be concerned about. Regarding the option comments in tsconfig, simply replacing them with a $schema field would suffice; don’t treat developers like idiots, managing them like a nagging mother.

RyanCavanaugh commented 1 week ago
{
    // For more info, see https://aka.ms/tsconfig
    "compilerOptions": {
        // File layout
        "rootDir": "./src",
        "outDir": "./dist",

        // Environment settings
        // See also https://aka.ms/tsconfig_modules
        "module": "nodenext",
        "target": "esnext",
        "types": [],
        // For nodejs:
        // "lib": ["esnext"],
        // "types": ["node"],
        // and npm install @types/node

        // Other outputs
        "sourceMap": true,
        // "declaration: true,

        // Stricter typechecking options
        // "noUncheckedIndexedAccess": true,
        // "exactOptionalPropertyTypes": true,

        // Style options
        // "noImplicitReturns": true,
        // "noImplicitOverride": true,
        // "noUnusedLocals": true,
        // "noUnusedParameters": true,
        // "noFallthroughCasesInSwitch": true,
        // "noPropertyAccessFromIndexSignature": true,

        // We recommend all of these options
        "strict": true,
        "verbatimModuleSyntax": true,
        "isolatedModules": true,
        "moduleDetection": "force",
        "skipLibCheck": true
    }
}
DanielRosenwasser commented 1 week ago

^ One issue with the above is that rootDir doesn't necessarily modify include, and as a result, a compilation can still include files outside of src while issuing an error. Not sure if it's just worth specializing the error message there.

ArnaudBarre commented 1 week ago

I think noFallthroughCasesInSwitch should be recommended. It can be a "style" to work with fall through, but I think for most people it would catch bugs

Also I would love this starter to document how to configure TS for bundlers:

/* If you compile/transpile your code with TS */
"outDir": "./dist",
"sourceMap": true,
// "declaration: true, // emit d.t.s

/* If you compile your code with a bundler, remove the section above and uncomment this one: */
// "moduleResolution": "bundler",
// "allowImportingTsExtensions": true,
// "noEmit": true,