Open kaleidawave opened 3 months ago
Note this is also an issue in TSC (https://github.com/microsoft/TypeScript/issues/12936).
Some cases are currently caught by ezno-checker because objects are treated dependently (for variables: it separates assignment restrictions from current values)
const x: {} = { b: "hi" }
const y: { b?: number } = x;
y.b satisfies boolean; // fails with = "hi"
(+ because of assignment tracking via events)
const x: { b: string } = { b: "hi" };
const y: {} = x;
const z: { b?: number } = y;
(function () { z.b = 5; })();
x.b satisfies string; // fails with = number
The issue is around what happens when we don't have the dependent types.
See my comment on TS Exact types here: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-2198567348
A value that is structurally typed (may have excess properties) cannot be safely assigned to a type that includes an optional property that is not present on the type of the value. Only an exact typed object or a fresh object (that we have full information on) can be assigned to a type with an additional optional property. I talked about a type that would work this was called a noextend type.
Spoken from a TS perspective - I'm not familiar with the workings of ezno. If I was making a rational type system I would make basic types work the noextend way instead of implementing them the TS way.
See my comment on TS Exact types here: microsoft/TypeScript#12936 (comment)
The link shoes a good example for a fail that can occur.
With any solution to this I would like to make it somewhat TSC compatible. Technically from subtyping rules excess properties are fine, the problem is that TSC removes information (etc the extra properties) for variable type annotations.
With the more dependent type system that is aware of mutations through side effects, your example should raise an issue already (or very soon from #157) from ezno check
.
Maybe there could be a flag so that all user code is subjected to all type object type annotations being treated as the upcoming Exclusive
helper will work?
The following with
?:
passes through the type system (at least will after #122) but throws at runtimeThis is also true for union types
The problem is sort of related to narrowing because the
v1.excess ??
performs narrowing (number | undefined -> number
). Maybe narrowing checks could be added during event application but would like to avoid that. (I should raise a related issue around getter property narrowing)The
Exclusive<...>
helper type (to be added in #157) can help here (although that is opt in and not in TSC). Maybe a mode could enforce this for assigning to unions and conditional properties. Want to not ignore this issue while also not creating something that is too strict (and creates a lot of breaking changes).