๐บ๏ธ RFC: Improve how we expose and name types #4633
chaance
announced in
Official RFCs
Replies: 1 comment 7 replies
-
Have you considered publishing types-only versions of |
Beta Was this translation helpful? Give feedback.
7 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Summary
This is a proposal to audit, simplify and improve the way we define and expose many of our types.
Example of bugs caused by duplicated types
Motivation
Given the modularity of Remix's design, we expose various types from different packages depending on the context in which they are used. This makes sense at first:
LoaderFunction
describes a server function, so you get that from your server adapter's package.MetaFunction
returns a set of props that are passed into<meta />
components that are rendered by React, so that type is imported from@remix-run/react
. A future@remix-run/vue
package would need to expose its ownMetaFunction
type adapted for Vue components.This becomes a problem for two reasons:
MetaFunction
is also described in@remix-run/server-runtime
because we still reference the meta object in runtime functions, but only a subset of its properties exist in that package.@remix-run/react
are extensions of other objects in@remix-run/server-runtime
, but because neither package is a dependency of the other, we essentially need to copy/paste types from one package to the other. This is a maintenance burden, makes it difficult to keep the types in sync, and because we use the same names across packages, it's not clear which types users are supposed use (and intellesense often chooses the wrong type).Proposal
A big hurdle to solving this problem is that there is no common dependency between many Remix packages. This is by design, but in truth there is always and underlying set of functions that make Remix what it is, and that is its router.
Since Remix was built on top of React Router, all of the routing logic exists in
@remix-run/react
. However with React Router v6.4, we moved its core logic (as well an many Remix features) into a framework-agnostic layer exposed in@remix-run/router
. Work is currently ongoing to upgrade Remix to use React Router 6.4, and the router package will be the beating heart of everything else in Remix. It makes perfect sense that it should be a dependency of both the server runtime and framework-specific packages.With most of the underlying types in the router, each environment-specific package can import and properly extend them. We should also consider renaming those types in the router package to something that is clearly generic and not meant to be used in Remix itself.
I also propose that
@remix-run/server-runtime
become a dependency of@remix-run/react
. Even if only its types are imported, none of Remix really makes much sense without the base runtime.Once we have shared dependencies, we will need to identify all of the duplicate and ambiguous types, decide on a more consistent naming scheme, and update our exports accordingly.
Drawbacks
With this change we are introducing dependencies that might not otherwise be explicitly necessary if not for TypeScript. IMO this is not an issue in practice because Remix users will always need the router, an adapter built on
@remix-run/server-runtime
, and a framework adapter to build anything with Remix anyway.It could be annoying for users who want to experiment with building their own fork of the server-runtime package. That shouldn't really be neccessary as long as their runtime supports proper web APIs (which it definitely should, and I don't know that we intend to work with those that don't).
Beta Was this translation helpful? Give feedback.
All reactions