Repository navigation
Two level deep indexed access: read works, write fails #47352
Description
Activity
Joe Calzaretta (@jcalz) seems you are right. I previously tested with a different return type for each of the Values with
interface Lookup { [A.First]: number [A.Second]: string } type Values = { [a in A]: { [b: string]: Lookup[a] }}
This is where 4.6 did come in to play. Simplifying the problem further I must have forgotten to check if it persisted in older versions. Have updated the issue.
- changed the title
[-]TS4.6 Two level deep indexed access of Mapped Type: read works, write fails[/-][+]Two level deep indexed access of Mapped Type: read works, write fails[/+]on Jan 9, 2022 - changed the title
[-]Two level deep indexed access of Mapped Type: read works, write fails[/-][+]Two level deep indexed access: read works, write fails[/+]on Jan 9, 2022 As Joe Calzaretta (@jcalz) pointed out it does seem related to #30769. In particular the following:
- Given a type variable T with a constraint C, when an indexed access T[K] occurs on the target side of a type relationship, index signatures in C are now ignored. This is because a type argument for T isn't actually required to have an index signature, it is just required to have properties with matching types.
function f3<T extends { [key: string]: any }>(obj: T) { let foo = obj['foo']; let bar = obj['bar']; obj['foo'] = 123; // Error obj['bar'] = 'x'; // Error }
If in this case
values[a]is typed asValues[T], does that mean that it in effect becomes theTwith constraintCthat is referred to in above quote from the PR, meaning its index signatures are ignored?- addedWorking as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
on Jan 11, 2022 RyanCavanaugh commented
on Jan 11, 2022 MemberMore actionsOn read you're allowed to fall back to the constraint type, but as noted above this isn't allowed during a write
Ryan Cavanaugh (@RyanCavanaugh) I can't say I understand why, that may be way above my pay grade :) But it seems to me
const valueB = values[a][b]; values[a][b] = valueB;
should never fail given no changes in
aandb.RyanCavanaugh commented
on Jan 11, 2022 MemberMore actionsTo correctly analyze that, the type of
valueBwould somehow have to encode that it came from the specific indices given byaandb. The type system is generally designed to track sets of values (types), not specific values or variables.- locked as resolved and limited conversation to collaborators
on Oct 22, 2025
Bug Report
Reading from a two level deep Indexed Access type works, but writing gives "Type cannot be used to index".
🔎 Search Terms
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Indexing a type while reading works, while writing fails with the same indexer.
🙂 Expected behavior
Indexed reads and writes both work when using the same indexer.