Skip to content

Array.isArray works bad with ReadonlyArray #43247

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
awerlogus opened this issue Mar 15, 2021 · 3 comments
Closed

Array.isArray works bad with ReadonlyArray #43247

awerlogus opened this issue Mar 15, 2021 · 3 comments
Labels
Fix Available A PR has been opened for this issue Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@awerlogus
Copy link

TypeScript Version: 4.3.0-dev.20210315

Search Terms: array isArray readonly

The first problem is that Array.isArray lets us violate readonly modifier and push values to ReadonlyArray:

declare const data: ReadonlyArray<any>

if (Array.isArray(data)) {
  // Expected: Error
  data.push(123)
}

The second problem is that Array.isArray doesn't filter out ReadonlyArray type:

declare const data: Record<string, any> | ReadonlyArray<any>

if (!Array.isArray(data)) {
  // now: readonly any[] | Record<string, any>
  // expected: Record<string, any>
  const alias = data
}
@MartinJohns
Copy link
Contributor

The first problem is that Array.isArray lets us violate readonly modifier and push values to ReadonlyArray:

This is most likely intentional. Be aware that readonly does not mean immutable. There is no way to represent immutability in TypeScripts type-system.

The second problem is that Array.isArray doesn't filter out ReadonlyArray type:

See #17002. Found using your search terms.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Mar 15, 2021
@RyanCavanaugh
Copy link
Member

This is the intended behavior. A regular array is a subtype of a ReadonlyArray (otherwise this hierarchy would not be useful). And if a type guard can't narrow down a type to a subtype (otherwise a type guard would not be useful).

@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Fix Available A PR has been opened for this issue Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
4 participants