Skip to content

ReadonlyArray with length should be narrowed in noUncheckedIndexedAccess #62719

Closed

Description

🔎 Search Terms

  • noUncheckedIndexedAccess
  • ReadonlyArray

🕗 Version & Regression Information

  • Errors up to v5.1.6
  • Does not error from v5.2.2
const arr: ReadonlyArray<number> & { length: 3 } = [1, 2, 3];
// Type 'number' is not assignable to type '3'.(2322)

Referenced:

⏯ Playground Link

https://www.typescriptlang.org/play/?noUncheckedIndexedAccess=true&ts=5.9.3#code/MYewdgzgLgBAhgJwQLhgJQKZwCbgDYCeAgknAQDxgCuAtgEYYIB8MAZDAN4x4ZgDmUABaoAzDAC+MALwwA2gEYANDABMykQF0A3ACgdoSLACWUDDWnwksgAzaYAensxq9RjAA+MKmGwYAZkZgGNg6QA

💻 Code

const arr: ReadonlyArray<number> & { length: 3 } = [1, 2, 3];

const item = arr[0]; // number | undefined

🙁 Actual behavior

Inferred as number | undefined in v5.9.3 (latest)

🙂 Expected behavior

Should be inferred as number from index 0 to 2

Additional information about the issue

I want to define a fixed length array and access if safely using noUncheckedIndexedAccess

Activity

  1. MartinJohns commented on Nov 5, 2025

    @MartinJohns
    Contributor

    Duplicate of #53678.

    I want to define a fixed length array and access if safely using noUncheckedIndexedAccess

    A fixed-length array would be a tuple, and if you use a tuple it works.


    I highly doubt your suggestion would get improved, because a viable workaround exists (use tuples), the intersection with the explicit length property has no effect on narrowing the ReadonlyArray<number> and the team expressed multiple times that they don't have any intention on improving the behavior of noUncheckedIndexedAccess.

  2. hyunbinseo commented on Nov 5, 2025

    @hyunbinseo
    Author

    If so, I guess a Tuple utility would be the only workaround:

    type Tuple<T, N extends number> = N extends N
    	? number extends N
    		? T[]
    		: _TupleOf<T, N, []>
    	: never;
    
    type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N
    	? R
    	: _TupleOf<T, N, [T, ...R]>;
    
    // [string, string, string, string, string]
    type String5 = Tuple<string, 5>;
  3. locked as resolved and limited conversation to collaborators on Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions