Repository: TypeScript
Issue: Writes to indexed access of an index signature are not sufficiently constrained
Labels: Suggestion,Experimentation Needed

### 🔎 Search Terms

"return type" "generic" "type parameter" "indexed access" "index signature" "assignable" "constraint"

### 🕗 Version & Regression Information

- This is the behavior in every version I tried, and I reviewed the FAQ for entries about index signatures

### ⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.7.2#code/C4TwDgpgBAogHgQwLZgDbQLxQN4CgpQIBcUA5AqflANoDWEIJAzsAE4CWAdgOYC6zbLt1wBfXLgAmEAMaoEraNID2nFlAiIU6EvGRoIuZauBR6IAIwCOPKFnKUNe9HQbnetspyUmKUAPR+UF7qrKxKrOJSsvKKKmpmAEwk9lAAPmQARg6a+i4gCe52Xj6k-oEQoeEANIRM6nCQ0sAQEkA

### 💻 Code

```ts
type Example = {
  a: 'a'
  [key: string]: string
}

declare const example: Example
const key1: string = 'a'
example[key1] = 'not a' // no error

declare const key2: 'a' | 'b'
example[key2] = 'not a' // error, as expected
//^^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.
```

### 🙁 Actual behavior

The index signature allows any `string` value to be assigned, ignoring the narrower type of `a`.

### 🙂 Expected behavior

Both property assignments in the above code should raise errors, for the same reason.

### Additional information about the issue

This is a more generalized version of #60700. @MartinJohns helped me realize that type parameters need not be involved.

Here's another pair of examples ([1](https://www.typescriptlang.org/play/?ts=5.7.2#code/C4TwDgpgBA6glgEwgJwCrmgXigbygQwH4AuKAZ2GTgDsBzAGigCMTzKbaoBfAKFEigBRAB74AtmAA2WXAVIByfPO5QAZLEQp0kHkgDGk-Mmh6A9tQpQIoidNIjxUiLogGjJ85YDWEEKR8gpgBmQjZOPNaO0gDaAQC6UNjy1KbABPJAA), [2](https://www.typescriptlang.org/play/?ts=5.7.2#code/C4TwDgpgBA6glgEwgJwCrmgXigbygbQGsIQAuKAZ2GTgDsBzAXXKpoagF8AoUSKAUQAeAQwC2YADZZcUYeQDkw+ZygAyWIhTpIXJAGMJw5ND0B7WlSgQR4qeSFjJEXRANGT5y8TJRvpgGYCNk5c1o5SRCSMUNjytKbAssoA9MlQ8VbIyKbIQA)) which I expected to be reasoned through similarly:
```ts
type WiderType = { a?: string, b?: string }
type Example = { a: 'a' } & WiderType
declare const example: Example
declare const key: keyof Example
example[key] = 'not a'
//^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.
```

```ts
type WiderType = { [key: string]: string }
type Example = { a: 'a' } & WiderType
declare const example: Example
declare const key: keyof Example
example[key] = 'not a' // no error
```

In both cases `Example` carries with it the information that the property `a` must have a value assignable to `'a'` (as can be seen with `example.a = 'not a'`). But this is not enforced when assigning to dynamic property using a key whose type matches the index signature.

[Here's another example](https://www.typescriptlang.org/play/?ts=5.7.2#code/C4TwDgpgBA6glgEwgJwCrmgXigbygbQGsIQAuKAZ2GTgDsBzKAH0pAFsAjAewBsBdclRoMoAXwBQoSFACiADwCGbMDyy4CxMpWp16AqAHIFBsVABksRCnSRx4pAGMeC5NAddaVKBEXLV5eSUVCHsIJxc3Dy9NQR0RFgp2bh5xHyDVIhI+KGwDWi5gKGMoAHoS72RkLmQAGiKKbzlIB2AIBCA) which does produce the error I expect:
```ts
type WiderType = { [key: string | symbol]: string }
type Example = { [key: string]: 'a' } & WiderType

declare const example: Example
declare const key: string | symbol
example[key] = 'not a' // error, as expected
//^^^^^^^^^^
// Type '"not a"' is not assignable to type '"a"'.
```