Repository: TypeScript
Issue: String index into a generic type having a string index signature isn't assignable to indexed access type
Labels: Suggestion,Needs Proposal

# Bug Report


### 🔎 Search Terms

string index signature; indexed access; generic; 2322; not assignable

### 🕗 Version & Regression Information

This seems to be there all the way back to TS3.5, maybe introduced by #30769, although I'm not sure I understand why.



-This changed between versions 3.3.3 and 3.5.1

### ⏯ Playground Link
[Playground link with relevant code](https://www.typescriptlang.org/play?target=9&ts=next#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChkHJwBcOyA2gNakDOYUoA5gLq31PIA+yAriACYQYoCP2QBfANz5CAI1LYK1ZHQYgWpEDwC2s6F14ChIsVJkEECpWzUbkszABsIcEAb6DhIUROnjcMHwIYMDobowQYAA8ANLIEAAekAI0yJQQAJ7oMGiYAHwAFDCYpBjoADRppDGVCTZMAJSlmOQxzOSqTMw45shQkTxQbsXoVO0JzJLIAPTT8VBQ6FAAhL2zyAAqGQAOKADkneoGWrr63A7ozq7uRl6ie8jAqSDoYEQ0NMCMIHCyzshgLBgHb7MqtdqHFh7AB0uH8uCAA)

### 💻 Code

```ts
interface Foo {
    a: { [k: string]: string | undefined };
    b: { [k: string]: number | undefined };
    c: { [k: string]: boolean | undefined };
}
function get<K extends keyof Foo>(foo: Foo, k: K, x: string): Foo[K][string] {
    return foo[k][x]; // error!
    // Type 'string | number | boolean | undefined' is not assignable to type 'Foo[K][string]'.
}
```

### 🙁 Actual behavior

Reading a property with a `string` key from a `Foo[K]` object does not produce a value of type `Foo[K][string]`, even in a non-widening position.

### 🙂 Expected behavior

Indexing into a `Foo[K]` value with a `string` key should produce a property of type `Foo[K][string]` if such a type is in a non-widening position.

---

This might be similar to #31661 and #33181 but I can't tell.  

Note that numeric index signatures work as expected:
```ts
interface Foo {
    a: { [k: number]: string | undefined };
    b: { [k: number]: number | undefined };
    c: { [k: number]: boolean | undefined };
}
function get<K extends keyof Foo>(foo: Foo, k: K, x: number): Foo[K][number] {
    return foo[k][x]; // okay    
}
```

And known literal keys work as expected:
```ts
interface Foo {
    a: { x: string | undefined };
    b: { x: number | undefined };
    c: { x: boolean | undefined };
}
function get<K extends keyof Foo>(foo: Foo, k: K, x: "x"): Foo[K]["x"] {
    return foo[k][x]; // okay    
}
```

But string index signatures (and symbol also) fail for some reason.

This can be worked around easily enough:
```ts
function get<K extends keyof Foo>(foo: Foo, k: K, x: keyof Foo[K]): Foo[K][keyof Foo[K]] {
    return foo[k][x]; // okay
}
````

But I'm wondering what's going on.

[Playground link with above examples](https://www.typescriptlang.org/play?ts=next#code/HYQwtgpgzgDiDGEAEAhArgcwEoRgewCcAXJAbwCgkqkBLYIiAgMwWQDE88zLreQAuMkgDaAa0FQiBOhgC6EqTKQAfJGmAATCEzoQNSAL4BuHryoAjQaRHikk6cDmDgaMOcYq1m7bv3HTZvBWNgoOTkjmnAA2ECDAnupaOsB6hia8BgFM6vBENHjxGBBEADwA0kgQAB4MmlBIohAAnnhMSBx4AHwAFEycgh0ANA2CZcNVoTIAlAOcwmWywvYystxm1ATFaATxfXhii1WyRkgA9KeVBASEAIQBvOdIACpNMMgA5MuOni5uHqqRPAxOIJbzJPTvWj1YB4EggKBQGgYUDmGJIIhcIivD4deaLL5yd4AOgCmXIZPIoEgsFYSAAcq5GDR4ABJbxVADKSNARG2EAA6oRRFA2Lo1tQ6AxmLSOuL1gIhGJnK53AR5HZFN9VIkfCk-Ol1hFgkqkL9Veqzf8vElfGl7tQgorbJa1YJAcD4tqwbb-Bksjk8gUkEVShVqrUNPVGi02h0entZnhhrYxkgJqaVYwZu05gthC7VhRDUhNrydkg9gdhEcTo88KIQE1eKTyOTW1ToHBEEgADI0KUgKJlZqCgjC0UpOW0eiMFjd2VFw0K6zpgmgm16u3FyxCdMu9e61K+w2Oldu6KxT3Ww-6lu8bLAXL5QrFcqVGoQOoNZqtHNdXr9H+yajOMggAERVGB2a4nmEFgYW9pUKW2y7HMoiHMcZwXPWjbNn6zZtu24CdrSHJNG4QIslAKDXI0wBPJwU6SrOMqMYu8rGrYUDkZEUTqmuXobkeBrrDu1gmtxFF8cqfwEAe4K3sWp4hHYPFAuq7qXvJPoiYY-qPoGL6hu+EZRj+sacPGgFDCMSCpqualRNBub4o5CHFsh5aVuh1aYY8jDXAQNxIC2hFEdSXbIKODbXIkTEztK85sYhSDLipBL8ZqGDaZux6iZxkyOBamZyYJN5bieBUamEGkXiCZUKRVVCZPeAbPsGr5hh+X7Rr+cYAXgibAXZoHfjGf54s5+x5r1FnTbI7mGp5qH7D5NZYUgOFNKFmRAA)

(note to self: go back to [this SO answer](https://stackoverflow.com/a/74020823/2887218) if I acquire more cluefulness here)