-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
f# Readonly on Exports from Namespaces (#16720)
namespace N {
export class C { }
}
N.C = class {};- Namespaces have had this feature for a while now
- Breaking changes for something that's functioned that way this long seems strange.
- Declined
Readonly & Variance
-
One thing that comes up quite a bit is strict variance.
-
If we enabled stricter variance, that would imply that
Arraybecomes invariant.- To get a covariant array, you need a
ReadonlyArray. - This means everything gets two declarations -
TandReadonlyT
- To get a covariant array, you need a
-
Strict variance is easy to enable, but would be hard to make easy to use.
-
This leads us to start thinking about how to quickly make a readonly version of a type.
-
We've had an experimental type operator called
readonly- Much like
keyof T, you just writereadonly T.
- Much like
-
Like the
Readonlymapped type, it makes all propertiesreadonlyas well.- However, the
Readonly<T>mapped type doesn't eliminate mutating methods at all.
- However, the
-
This means we needed to add a way to indicate that a method doesn't mutate its object.
- Created the
this: readonlysyntax.
- Created the
-
Example:
class Foo { name: string; getName(this: readonly): string; setName(value: string): void; } // This: type ReadonlyFoo = readonly Foo; // ... is equivalent to this: type ReadonlyFoo = { readonly name: string; readonly getName(this: readonly): string; }
-
What about deep readonly?
- In other words, does
readonly Foo[]give you areadonly Array<readonly Foo>? - Have thus far decided no.
- Could create an
immutabletype operator- Q: Couldn't you implement that with mapped types?
- A: Potentially
- May be a bit confusing since state could be captured outside of current object
- Q: Couldn't you implement that with mapped types?
- Could create an
- In other words, does
-
In
--strictReadonlymode, thisreadonlyoperator would work as described above.readonly Tnot assignable toT.readonlyprops would not be assignable to mutable props.readonly Tremoves mutating methods
-
Outside of
strictReadonly,readonly Tis justReadonly<T> -
All of this means that library authors would need to enable readonly mode.
-
Would TypeScript be able to infer whether a method is readonly or not?
- Kind of tricky, methods transitively call each other.
-
How bad are strict variance modes without this?
- Special hell for passing callbacks.
- Need a
superconstraint for generics - otherwise many types stay invariant by virtue of taking aTas an input position.
-
Will people know how to use
this: readonly?- Seems like people will always need to be mindful of this when they write
.d.tsfiles. - How will we generate this for the DOM if the metadata isn't present? What about
readonly HTMLElement?
- Seems like people will always need to be mindful of this when they write
-
How do
this: readonlyparameters work with overloads?- Currently, if any overloads are not declared with
this: readonly, the property is eliminated. - That's not going to play well with libraries.
- Example: Knockout.
- Currently, if any overloads are not declared with