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

make Type, Props etc immutable #676

Open
adrian-gierakowski opened this issue Nov 23, 2022 · 2 comments
Open

make Type, Props etc immutable #676

adrian-gierakowski opened this issue Nov 23, 2022 · 2 comments

Comments

@adrian-gierakowski
Copy link

🚀 Feature request

The goal of this request is to be able to use io-ts in projects where @typescript-eslint/prefer-readonly-parameter-types is enabled (without having to disable the rule each time various io-ts types are used as function parameters).

Current Behavior

I get a linter error when declaring functions parameter of certain io-ts types

Desired Behavior

No linter errors

Suggested Solution

Currently Props and other cases where [key: string]: T is used are mutable. These should be replaced by readonly versions.

Additionally, class methods on Type (and possibly others) are not immutable (see: this issue). A workaround would be the define methods as readonly properties. For example:

  readonly asDecoder = function asDecoder(this: Type<A, O, I>): Decoder<I, A> {
    return this
  }

instead of:

io-ts/src/index.ts

Lines 196 to 198 in 4edbeb3

asDecoder(): Decoder<I, A> {
return this
}

Who does this impact? Who is this for?

All io-ts users who wish to enable @typescript-eslint/prefer-readonly-parameter-types

Describe alternatives you've considered

Additional context

Your environment

Software Version(s)
io-ts ^2.2.19
fp-ts ^2.5.0
TypeScript 4.7, 4.8
@ragnese
Copy link

ragnese commented Jun 14, 2023

I'm not affiliated with this project, so my opinion doesn't matter.

I don't see any harm in marking a bunch of these fields as readonly, of course (why would someone need to modify, e.g., a props value?)...

But, I really feel like readonly on object properties is such a broken feature of TypeScript that it's not worth even using it at all except maybe as a library author simply to communicate intent to consumers of your public API. Here's why readonly is basically useless:

type Foo = {
    i: number
}

type ReadonlyFoo {
    readonly i: number
}

function useFoo(foo: ReadonlyFoo) {
    /* The next line would give a compile error--darn.
     * foo.i = 3
     */
    // But these lines won't!
    const mutableFoo: Foo = foo
    mutableFoo.i = 3 // mutates the input argument!
}

Add to that the pain of working with some APIs that use readonly and some that don't, and it can get pretty tedious for very little "safety".

Not that readonly arrays actually work mostly okay because the TypeScript compiler has lots of custom analysis for them, and knows what standard library methods are mutating, etc. For some reason, they just haven't implemented readonly on objects very well, IMO.

Basically, my point is that I think that ESLint lint is not worth using, anyway.

@adrian-gierakowski
Copy link
Author

Yes, I’m ware of these issue and kind of gave up on this mainly due to issues which arise when interfacing with 3rd party libs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants