Skip to content

Distinguish types PmOutbox vs. StreamOutbox more fully#4998

Merged
chrisbobbe merged 4 commits intozulip:mainfrom
gnprice:pr-outbox-types
Sep 11, 2021
Merged

Distinguish types PmOutbox vs. StreamOutbox more fully#4998
chrisbobbe merged 4 commits intozulip:mainfrom
gnprice:pr-outbox-types

Conversation

@gnprice
Copy link
Copy Markdown
Member

@gnprice gnprice commented Sep 11, 2021

This expresses that the types of certain properties on Outbox vary together, and that they do so in the same way as on Message.

That in turn means that when we have a condition like type === 'stream', Flow can infer that display_recipient will be a string (the stream name) rather than an array, and so on.

Also make some followup simplifications that this opens up.

(One upcoming place I suspect this will simplify the code a bit is at #4899 (comment) Hmm, no -- that code wants stream_id, and that's something we don't yet have on Outbox: #3998. Ah well, this will simplify that code once we also have #3998.)

This expresses that the types of these properties `type`, `subject`,
and `display_recipient` vary together, and that they do so in the
same way as on `Message`.

That in turn means that when we have a condition like `type ===
'stream'`, Flow can infer that `display_recipient` will be a string
(the stream name) rather than an array, and so on.
These two asserts just confirmed that the `type` and
`display_recipient` properties varied together in the expected way,
in order to assure Flow that after checking `type` we'd get the
right type of value out of `display_recipient`.

Now that we've expressed that tandem variation directly in the actual
types, we can drop the asserts.
$Shape is not very sound -- Flow will sometimes treat the result as if
it definitely has all the original object type's properties.

Instead, use `$Rest<Foo, { ... }>` here, just as we do for
`streamMessage` and others in this file.

In fact, as a bonus simplification, fuse this use of `$Rest` with an
inexact object type (for making everything optional) with the existing
use of `$Diff` with an exact object type (for excluding a specific
property), resulting in a single `$Rest` with a combined type.
This is really an internal bit of how we go about constructing the
types PmOutbox and StreamOutbox; it doesn't make much sense for types
elsewhere in the application to refer to it.

There was one place we'd been referring to it, at `outboxMessageBase`
in `exampleData`, and that illustrates the point.  Drop that type
annotation entirely.

Like `messagePropertiesBase`, this value is an internal helper used
narrowly just within this module; its real type, in terms of the
promise made in its interface, is "whatever the call site needs".

Flow inherently checks that it satisfies *that* type.  (Try it, after
this change: delete one of the properties in the `outboxMessageBase`
definition, and see an error appear where it's used in `streamOutbox`.
This only works after the preceding commit which fixed
`streamOutbox`'s use of the unsound `$Shape`.)

And on the other hand, writing out what the type works out to
explicitly is kind of verbose and just a recipe for confusion.
@chrisbobbe chrisbobbe merged commit 14fb5e1 into zulip:main Sep 11, 2021
@chrisbobbe
Copy link
Copy Markdown
Contributor

Thanks, LGTM! Merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants