Repository: TypeScript
Issue: Compiler option to switch lib .d.ts `any`s to `unknown`
Labels: Suggestion,Needs Proposal

### 🔍 Search Terms

compiler option flag lib.d.ts noImplicitAny unknown any

### ✅ Viability Checklist

- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ Suggestion

A few built-in (`lib*.d.ts`) types include `any`, even though `unknown` would be safer. Most notably:

* [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse): https://github.com/microsoft/TypeScript/blob/56a08250f3516b3f5bc120d6c7ab4450a9a69352/src/lib/es5.d.ts#L1144
* [`.json()`](https://developer.mozilla.org/en-US/docs/Web/API/Response/json): https://github.com/microsoft/TypeScript/blob/56a08250f3516b3f5bc120d6c7ab4450a9a69352/src/lib/dom.generated.d.ts#L19416
* [`Storage`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#basic_concepts): https://github.com/microsoft/TypeScript/blob/56a08250f3516b3f5bc120d6c7ab4450a9a69352/src/lib/dom.generated.d.ts#L22262

These are kept as `any` for legacy support reasons: it would be a massive breaking change to restrict them to `unknown`. But, for newer projects and those that don't rely on those `any`s, switching them to `unknown` would be much safer long-term.

Proposal: could we have a compiler option to switch the lib definition `any`s to `unknown`s? Maybe, `strictLibDefinitions`? `useUnknownInLibDefinitions`? _(I'm not convinced of those specific names)_

### 📃 Motivating Example

Using this compiler option will prevent many of the common `any`s from sneaking into projects that use built-ins such as `JSON.parse` and `Response`.

For example, this code does not have a type error by default, but would with the new compiler option enabled:

```ts
const data = JSON.parse(`"clearly-a-string"`);
//    ^? any (today)
//    ^? unknown (with this compiler option)

console.log(data.some.property.that.does.not.exist);
```

### 💻 Use Cases

I'm not sure that this could even be enabled with `strict` anytime soon. It might introduce a lot of type errors in even many projects that are already in strict mode but happen to use `JSON.parse` et al.

This is not the same as #27265. That issue tracks a flag to handle implicit `any`s differently. This is for a flag to change the definitions in TypeScript's built-in `.d.ts` files.

I don't _think_ this is the same as https://github.com/microsoft/TypeScript/issues/26188. Per https://github.com/microsoft/TypeScript/issues/60899#issuecomment-2567457149: I'd interpreted that one as suggesting making the change always - with varying levels of compiler-option-orientation in the comments.

The implementation details of this might be tricky. The dom lib generator could theoretically produce two `.d.ts` outputs for each of today's files: one with `any` and one with `unknown`. Or, if two files aren't doable, there could be an intrinsic declared that switches between `any` and `unknown`.