Description
Casing Operators on string
// this DOES NOT get uppercased
type A = Uppercase<`a${string}`>;
- Clearly we should switch that to something at least like
`A${string}`
. - If these operators are going to operate the templates, it feels like there should also be a corresponding representation for
Uppercase<string>
too. - So now we will map over the templates and distribute over type interpolations/holes (e.g. replacing the
string
withUppercase<string>
in the above example). - When we built these intrinsics, we really didn't want the compiler to "deeply" understand them.
- Now we will have to also have to be able to ask "is this intrinsic operator generic?"
Uppercase<Uppercase<T>>
simplifies to justUppercase<T>
.Uppercase<Lowercase<T>>
does not?- These don't round trip.
- What?
- German S, Turkish i
- 😫
- Conclusion: in favor of this, just need a code review.
Records and Tuples
tc39/proposal-record-tuple#9
https://gist.github.com/rbuckton/bac946eda028cd898e7b09498e6f12e8
-
Getting feedback from type systems on Records/Tuples.
-
Can't use
ReadonlyArray
to represent tuples. -
Records and Tuples can only contain primitive values (e.g.
string
,number
,symbol
,boolean
, etc.). -
Primitive
tuple
and primitiverecord
types as constraints likeobject
. -
Idea would be
Record
andTuple
prototypes for apparent types. -
Possibly provide
ReadonlyRecord
andReadonlyTuple
types.- This avoids conflicting with the built-in
Record
type.
- This avoids conflicting with the built-in
-
Can also create record/tuple syntax.
type T = #[number, string]; // equivalent to type T = tuple & { readonly 0: number; readonly 1: string; readonly length: 2; };
-
Also a
box
type. Box is still a name that's being bikeshed-ed. Could imaginebox<T>
- first primitive that's generic. Could also make abox
type operator. -
Could we use a type alias for
Box
?Box
has a prototype, has primitive semantics.
-
Copying the syntax for creating primitives from array tuples and object literals.
-
Other projects might already use
tuple
andrecord
, but maybe not a blocker. -
A key type of records/tuples is that they're deeply immutable; but property access syntax is the same.
- To support writing code like that, we don't let
readonly
ness affect assignability today. - Do we need to tighten the behavior somehow?
- To support writing code like that, we don't let
-
More concerns with just that - also the fact that a lot of places don't expect object-like things that are not objects.
-
Trying to decide if this provides enough value for the complexity.
-
How do you explain to users which "types of objects" they should be using?
-
Fair amount of overlap with "blittable" types - feels odd that these types with value semantics are not leveraged that way at all.
- Explicitly not TypedArrays or blittable types.
-
What's the biggest use-case? Composite keys?
- Referential transparency.
- No persistence, right?
- You already have persistent data structures with object types.
-
Seeing syntax for
#
in front of objects - why not tagged objects? -
We'd also need some way to refer to "array-based tuple or immutable tuple".
-
Big concern over cognitive overhead - which do you use, why can't I define my own custom records, etc.
-
A lot of this is nice - makes sense. Some on the team feels like
box
is actually good. -
Then complexity with the type system itself is also very high. How do you avoid bifurcating the world?
- The minute you push strict readonliness, you split the world into mutable/immutable.
- Nobody says readonliness by default.
-
Also, freshness rules - do properties get the
as const
semantics? If so, you can't reassign.- Use the same mutability binding rules as today - a
let
means widen the recursive properties,const
means don't. - Really uninuitive!
let
/const
always signaled just top-level mutability. Now they impact the properties of the value.
- Use the same mutability binding rules as today - a
-
Also have a community PR from @Jack-Works (feat: support parser of record and tuple #45546).
- Scope is rather large and a lot of decisions we're still unclear about. We don't want to move too quickly on an implementation, and when the time comes it may be better to iterate on it from within the team.