Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Default to ReadonlyArray #32467

Closed
waterplea opened this issue Jul 18, 2019 · 14 comments
Closed

Default to ReadonlyArray #32467

waterplea opened this issue Jul 18, 2019 · 14 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@waterplea
Copy link

Search Terms

ReadonlyArray, default

Suggestion

By default type for array is inferred as Array. It would be better to default to a more strict ReadonlyArray and if programmer needs mutability — he would explicitly state so. Could be a tsconfig option to not introduce a breaking change.

Use Cases

readonly value = [0, 1, 2, 3]; // <-- type number[] here

Examples

readonly value = [0, 1, 2, 3];
readonly mutableValue: Array<number> =  [0, 1, 2, 3];

Checklist

My suggestion meets these guidelines:

  • [✓] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [✓] This wouldn't change the runtime behavior of existing JavaScript code
  • [✓] This could be implemented without emitting different JS based on the types of the expressions
  • [✓] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [✓] This feature would agree with the rest of TypeScript's Design Goals.
@AnyhowStep
Copy link
Contributor

Are you saying you want,

//ts
export const arr = [1,2,3];

To emit,

//.d.ts
export const arr : readonly number[];

?

@waterplea
Copy link
Author

@AnyhowStep I'm not familiar with the syntax you used in your .d.ts. I want a tcsconfig option for

//ts
export const arr = [1,2,3];

to emit

//.d.ts
export const arr: ReadonlyArray<number>;

@demensky
Copy link

demensky commented Jul 19, 2019

class Test {
    readonly value = [0, 1, 2, 3] as const; // <-- type `readonly [0, 1, 2, 3]` here
}

@waterplea
Copy link
Author

waterplea commented Jul 19, 2019

I see. Thanks @demensky so there's this (was not familiar with this feat):
https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#const-assertions
That's a bit shorter than explicitly stating ReadonlyArray but in terms of arrays I like never use mutability and very rarely do for objects, it would be great if I could force that thing on a tsconfig level like I can force things like strict null checks, no implicit any, strictPropertyInitialization, stuff like that.

EDIT: Maybe this issue can be turned into:

Option to default to as const for objects and arrays with added as mutable assertion for mutability

@fatcerberus
Copy link

Do note there's a subtle difference - as const when applied to an array literal infers a tuple, not an array. At runtime tuples and arrays are the same of course, but there are differences in how the type system treats them.

It also infers the strictest possible type for each element (literal type) rather than the more general number or string, so that's something to keep in mind too.

@waterplea
Copy link
Author

@fatcerberus true, that's why I'm focusing on array and object since it wouldn't matter for them for the most part, and for numbers and strings we can just declare them as const and not let.

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Jul 31, 2019
@lautarodragan
Copy link

lautarodragan commented Aug 8, 2019

I'd like this feature, but TypeScript should remain intuitive to plain JavaScript users IMO, so it should live behind a -strict-array-immutability flag.

I'd also love to have this for interface properties, defaulting to readonly with a -strict-interface-immutability flag and having to mark mutable ones with a mutable keyword, as such:

interface T {
  n: number // immutable
  mutable s: string // mutable
}

const o: T = {
  n: 42,
  s: 'hello world',
}

o.n = 43 // error
o.s = '👋🌎' // ok

The interface is a separate suggestion and should probably live in its own GitHub issue, but it makes sense to mention it in this discussion since the semantics/syntax should be similar.

Related: #22315, this comment in particular also requests a flag under the strict umbrella for readonly-by-default.

@thehappycoder
Copy link

Good idea! However, I would like it also for interface properties. At the moment, my code has too much readonly keywords.

@Shinigami92
Copy link

readonly value = [1, 2, 3, 4, 5] means only that you cant reassign value
But you can add more elements into value, so value.push(6) works fine

@safareli
Copy link

safareli commented May 4, 2020

Having a flag which will turn on "assume everything is read only" would be great!

I'm using readonly in all the places and it's too noisy. I would prefer mutable flag for places where I do need mutation which I don't in 99% of the time.

UPDATE: I've opened proposal for this here #42357

@anilanar
Copy link
Contributor

@safareli's suggestion should be a proposal by its own, probably. The problem is, how will we consume 3rd party libraries which cannot have their own flags scoped to their code? Library ecosystem would be divided into 2 which is not desirable.

We probably need per module/file flags like Haskell's lang. extensions. It would behave similar to the @jsx pragma. Only a subset of flags can be used with in-file pragmas. So gotta extend @jsx pragma feature to a more generic feature.

@MartinJohns
Copy link
Contributor

Library ecosystem would be divided into 2 which is not desirable.

This is already the case since strictNullChecks was introduced in TypeScript 2.0 (in 2016). Even nowadays many popular libraries are lacking type-safety by not utilizing the strict compiler flags.

@safareli
Copy link

@anilanar I've opened the proposal #42357

@waterplea
Copy link
Author

I think we can close this one in favor of the proposal above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests