Repository: create-react-app
Issue: Support for project references
Labels: issue: proposal,tag: enhancement,issue: typescript

### Is your proposal related to a problem?

I'm using create-react-app for [my React workshops](https://github.com/topics/epicreact-dev). Each project has an exercise file (the unfinished code) and a final file (the finished code). I'm rewriting them all to TypeScript. I don't want to enable strict mode for the exercise files because it can be difficult for people new to TypeScript. However I do want the final version of the exercise to be type checked with strict mode (for my own sake).

Having different configs for different files in a project can be accomplished using [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) configuration. Here's what I've done to make this "work": https://github.com/kentcdodds/react-fundamentals/commit/84eb9ed2f10a060898d115e768df77c8dc603d46

**tsconfig.json**

```json
{
  "files": [],
  "references": [
    {"path": "config/tsconfig.exercise.json"},
    {"path": "config/tsconfig.final.json"}
  ]
}
```

**config/tsconfig.exercise.json**

```json
{
  "extends": "./tsconfig.shared.json",
  "include": ["../src/exercise/"],
  "compilerOptions": {
    "strict": false
  }
}
```

**config/tsconfig.final.json**

```json
{
  "extends": "./tsconfig.shared.json",
  "exclude": ["../src/exercise/"],
  "include": ["../src"],
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true
  }
}
```

**config/tsconfig.shared.json**

```json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noFallthroughCasesInSwitch": true
  }
}
```

Running `tsc -b` will typecheck all the files with the expected configuration.

However, as soon as I run `react-scripts start`, my `tsconfig.json` gets [changed](https://github.com/kentcdodds/react-fundamentals/commit/e266ea6a2e6fec4d622f4ae7896cb05e2ab710b1):

```json
{
  "files": [],
  "references": [
    {
      "path": "config/tsconfig.exercise.json"
    },
    {
      "path": "config/tsconfig.final.json"
    }
  ],
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}
```

With those changes, when I try to run `tsc` (or `tsc -b`), I get several errors, for example:

```
tsconfig.json:4:5 - error TS6306: Referenced project '/Users/kentcdodds/code/epic-react/react-fundamentals/config/tsconfig.exercise.json' must have setting "composite": true.

4     {
      ~
5       "path": "config/tsconfig.exercise.json"
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6     },
  ~~~~~

tsconfig.json:7:5 - error TS6310: Referenced project '/Users/kentcdodds/code/epic-react/react-fundamentals/config/tsconfig.final.json' may not disable emit.
```

By setting `"noEmit": false` and `"composite": true` to the `config/tsconfig.shared.json`, I get a little further, but can't get rid of this error:

```json
error TS6305: Output file '/Users/kentcdodds/code/epic-react/react-fundamentals/src/final/07.extra-3.d.ts' has not been built from source file '/Users/kentcdodds/code/epic-react/react-fundamentals/src/final/07.extra-3.tsx'.
  The file is in the program because:
    Matched by include pattern 'src' in '/Users/kentcdodds/code/epic-react/react-fundamentals/tsconfig.json'

  tsconfig.json:33:5
    33     "src"
           ~~~~~
    File is matched by include pattern specified here.
```

I've tried all combinations of options I can think of and nothing I can think of will make TypeScript happy + accomplish my goal of having a different config for different files in my create-react-app project.

### Describe the solution you'd like

I would like support for `references` directly. I did notice [ts-loader's page on references](https://github.com/TypeStrong/ts-loader/blob/master/REFERENCES.md).

Short of that, I would be happy with an environment variable (similar to `SKIP_PREFLIGHT_CHECK`) which opts-out of updating the `tsconfig.json` and just trusts that the config works as-is.

### Describe alternatives you've considered

I've thought about switching off of create-react-app or using one of the off-shoot projects that are flexible, but I'd really prefer to not do that.

### Additional context

I think I've said everything that needs to be said 😅