Repository: TypeScript
Issue: noUncheckedIndexedAccess - disable per type or property (use case: dynamic Proxy which returns value for every prop)
Labels: Suggestion,Awaiting More Feedback

# Suggestion

`noUncheckedIndexedAccess` - disable per type or property (use case: dynamic Proxy which returns value for every prop)
<!--
  Please fill in each section completely. Thank you!
-->

## 🔍 Search Terms

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

noUncheckedIndexAccess, proxy, disable

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [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 feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->

Now that #13778 is implemented and it works nicely for most of the cases, increasing type safety, I would like to ask if you would consider providing a way to disable it on a type/prop level.

## 📃 Motivating Example

<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->
We like the new rule and we enabled it in our codebase. But in some specific cases (e.g. a dynamic Proxy which always returns a value for any property or any dynamic getter) we would like to have a possibility to disable/override it.

I provided a simple example below, but we use it to a greater extent incl. nested proxies, dynamic tree-like structures etc. all the dynamic magic stuff javascript is meant for 🙈

In order to improve DX we would also like to avoid sprinkling non-null assertion operators everywhere we use them, like
`const a = foo.something()!.nested()!.etc!`

I tried overriding index signature types with `NonNullable`, `Required`, `Exclude`, index signature modifier `-?` etc. but no luck.

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->

In this simple example, `foo` is a proxy which returns name of dynamically accessed property as string. It will always be a string, so undefined should be excluded.

```typescript
// tsconfig.json
{ "compilerOptions": { "noUncheckedIndexedAccess": true } }

interface DynamicProxy {
  [key: string]: string;
}

// Proxy which always returns string value for any property
const handlers: ProxyHandler<DynamicProxy> = {
  get(target, propKey, receiver) {
    if (typeof propKey === 'symbol') return propKey.toString();
    return propKey;
  },
}

const foo = new Proxy<DynamicProxy>({}, handlers);

const something: string = foo.something;
// Type 'string | undefined' is not assignable to type 'string'.
//  Type 'undefined' is not assignable to type 'string'.(2322)
```

[[ playground ]](https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true#code/JYOwLgpgTgZghgYwgAgCIE8RwLbAQBSgHsAPdZAbwChlkBtAawnQC5kBnMKUAcwF02nbiB4BuKgF8qVBERCdkACzggAJgBto7NoVLoAEio3QAPBiy4CxMgD5kAXko1kPCGAAUYOFFdgANMgADsSBANLMAVAQSMAAbtAAlE60tMAwyJ7ogRBE6cFEYcwO9o4A5Ozo2ABGROqlSVFgAK5QIEEh4egAdGBEAMpcvO4J4inIjS1t+YXoo8gSfpLSsvJgyDBERA7IIBAA7si6ZGaYOHhH6DbuFAtKRppQ7CPLcgrsRNhuiryCgyLbGyIXXenzA3xE4iAA)