Closed
Description
Immutability
- No concrete ideas yet, but here's the background.
- Many users prefer to program in a very immutable style.
- If you think about the differences between C# and F#, one of the the things that makes functional programming easier in the latter is immutability by default.
- But JavaScript doesn't have a library that's amenable to using immutable data structures.
- So what might the world look like here?
- Perhaps some way to declare an immutable type is mutable?
- Perhaps a way to say all fields declared in a type are immutable by default, mutable as an opt-in.
- But even that's not enough for us - we use a "lazy initialization" pattern where after creation we set the value of a field exactly once.
- What about something that differentiates the API layer versus within the compilation itself?
- Depends what's considered your code and what's considered external code in some cases, and we don't have a way of indicating what's part of the API.
- [[Now we're derailing into how you expose your public API surface]]
- Then should we have opaque types?
- Well you can sort of do it today.
- The idea of immutability has some of the benefits of and is related to generally restricting access to the internals of your programs.
- Then should we have opaque types?
Experimental Stage 1/2 Proposals
- If you use decorators today, you get a warning that decorators are experimental.
- But many users are not aware that their decorators are experimental because they start off with a
tsconfig
that already turns--experimentalDecorators
on!
- But many users are not aware that their decorators are experimental because they start off with a
- Generally we only take stage 3 features now.
- Idea
- Don't do anything without an
--experimentalStage1Or2
flag (bikeshed on name later) - Give a warning all the time which you cannot turn off.
- Don't do anything without an
- The thing is, nobody uses these features to experiment with. They're putting this code into production.
- So now you're dangling this feature under people's noses but giving a warning that people will become numb to.
- Conclusion: we can put branches on GitHub, but we don't want to put people in difficult upgrade paths.
Match types
Still in prototyping phase.
type X<T> = match (T) {
number: "a",
string: "b",
else: "c"
}
type A = X<number>; // has type `"a"` - matches with `number`
type B = X<1 | "hello">; // has type `"a" | "b"` - `"hello"` and `1` are subtypes of `number` and `string`
type C = X<object> // has type `"c"` - fell into the `else` branch
One concern (a.k.a. a feature!) is that this allows us to branch.
type Conditional<C, T, F> = match (C) {
true: T,
false: F,
}
This all arose from discussion around the awaited
type PR where many people requested a more general solution.
With awaited
, we'd have functionality like so:
type X = awaited Promise<Promise<number>>;
// X = number
We need a way to introduce type parameters to emulate this
type Awaited<T> = match (T) {
PromiseLike<infer U>: Awaited<U>,
else: T,
}
We would need to add some recursion checks like we do in other resolution algorithms.
Main question: what about the higher order type relationships? It's effectively like trying to relate two switch statements.