tslint-immutable icon indicating copy to clipboard operation
tslint-immutable copied to clipboard

Prefer ReadOnly<T> over readonly keyword

Open elldritch opened this issue 8 years ago • 5 comments

Using Readonly<T> is much more readable than marking every property as readonly.

elldritch avatar Dec 10 '17 01:12 elldritch

So if I understand you are proposing to use:

interface FooMutable {
  bar: string
}
type Foo = ReadOnly<FooMutable>

Or perhaps:

type Foo = ReadOnly<{
  bar: string
}>

The second option would not give an interface but instead a type I think. Is there a shorter way to write it and still use an interface?

jonaskello avatar Dec 10 '17 10:12 jonaskello

I actually prefer types over interfaces in my code, so I'm not very familiar with how this would work on interfaces. I'm not sure if there's a way to create mapped interfaces (a la mapped types).

Maybe it would make sense to use this rule only for types?

elldritch avatar Dec 11 '17 06:12 elldritch

Yes, I think making a new rule that only apply for types would make the most sense. Something like readonly-type. AFAIR ReadOnly<T> creates a mapped type which adds the readonly modifier on all members.

So the rule would check for type alias declarations (TypeAliasDeclaration) that declares an alias for type literals (TypeLiteral).

So it would warn for this case:

type Foo = {
  bar: string
}

But ignore this case:

type Foo = number;

Is there more cases we need to check for?

jonaskello avatar Dec 28 '17 14:12 jonaskello

type Identity<T> = T;

export interface Bar extends Identity<{foo: string}> {}

should also be check, no?

gabejohnson avatar Dec 27 '18 16:12 gabejohnson

The second option would not give an interface but instead a type I think. Is there a shorter way to write it and still use an interface?

interface Foo extends Readonly<{
    myProperty: string;
    myOtherProperty: number;
}> {};

I think this looks pretty readable. At least when there are a lot of properties. Compare to how it currently looks:

interface Foo {
    readonly myProperty: string;
    readonly myOtherProperty: number;
};

geon avatar Mar 01 '19 10:03 geon