Skip to content

Default to ReadonlyArray #32467

Closed
Closed

Description

@waterplea

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.

Activity

  1. AnyhowStep commented on Jul 18, 2019

    @AnyhowStep
    Contributor

    Are you saying you want,

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

    To emit,

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

    ?

  2. waterplea commented on Jul 19, 2019

    @waterplea
    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>;
  3. demensky commented on Jul 19, 2019

    @demensky
    class Test {
        readonly value = [0, 1, 2, 3] as const; // <-- type `readonly [0, 1, 2, 3]` here
    }
  4. waterplea commented on Jul 19, 2019

    @waterplea
    Author

    I see. Thanks Dmytro Demensky (@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

  5. fatcerberus commented on Jul 19, 2019

    @fatcerberus

    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.

  6. waterplea commented on Jul 19, 2019

    @waterplea
    Author

    Bruce Pascoe (@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.

  7. lautarodragan commented on Aug 8, 2019

    @lautarodragan

    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.

  8. thehappycoder commented on Jan 19, 2020

    @thehappycoder

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

  9. Shinigami92 commented on Jan 27, 2020

    @Shinigami92

    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

  10. safareli commented on May 4, 2020

    @safareli

    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

  11. anilanar commented on Jan 15, 2021

    @anilanar
    Contributor

    Irakli Safareli (@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.

  12. MartinJohns commented on Jan 15, 2021

    @MartinJohns
    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.

  13. safareli commented on Jan 15, 2021

    @safareli

    Anıl Anar (@anilanar) I've opened the proposal #42357

  14. waterplea commented on Nov 8, 2021

    @waterplea
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions