-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(remix-server-runtime): reimplement Jsonify
type utility
#7605
Conversation
🦋 Changeset detectedLatest commit: be4cb07 The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@pcattori - I've recently noticed your PR, and I indeed believe that it makes sense to repatriate this logic back to Remix, especially since the adoption of However, I'd like to bring to your attention the following PR I had submitted for type-fest: sindresorhus/type-fest#690 This PR addresses an issue with |
To help you understand the gist of the problem, please find bellow an example of a patch: diff --git a/packages/remix-server-runtime/jsonify.ts b/packages/remix-server-runtime/jsonify.ts
index 9531f3d51..ebdbd67c0 100644
--- a/packages/remix-server-runtime/jsonify.ts
+++ b/packages/remix-server-runtime/jsonify.ts
@@ -5,6 +5,9 @@ export type Jsonify<T> =
// any
IsAny<T> extends true ? any :
+ // toJSON which is tested first in case an object also implement a "JSONPrimitive" interface
+ T extends { toJSON(): infer U } ? (U extends JsonValue ? U : unknown) :
+
// primitives
T extends JsonPrimitive ? T :
T extends String ? string :
@@ -21,9 +24,6 @@ export type Jsonify<T> =
// Not JSON serializable
T extends NotJson ? never :
- // toJSON
- T extends { toJSON(): infer U } ? (U extends JsonValue ? U : unknown) :
-
// tuple & array
T extends [] ? [] :
T extends readonly [infer F, ...infer R] ? [NeverToNull<Jsonify<F>>, ...Jsonify<R>] :
@@ -140,6 +140,7 @@ export type _tests = [
Expect<Equal<Jsonify<Date>, string>>,
Expect<Equal<Jsonify<{ toJSON(): undefined }>, unknown>>,
Expect<Equal<Jsonify<{ toJSON(): Date }>, unknown>>,
+ Expect<Equal<Jsonify<BooleanWithToJson>, string>>,
// tuple & array
Expect<Equal<Jsonify<[]>, []>>,
@@ -244,3 +245,7 @@ type EmptyObject = { [emptyObjectSymbol]?: never };
// adapted from https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts
type IsAny<T> = 0 extends 1 & T ? true : false;
+
+interface BooleanWithToJson extends Boolean {
+ toJSON(): string;
+}
p.s: I like your approach of simply collocating the typecheck-only tests in the file directly 👍🏽 EDIT: you might prefer to move the |
3554a2f
to
ae89597
Compare
@nrako thanks for the suggestion! I included your improvement and added you as a co-author for that commit |
defer typings require `defer()` helper and do not support plain objects returned by loaders
also remove redundant test for hook types
testing `any` type doesn't actually test anything
Co-authored-by: Nicholas Rakoto <nico@nrako.com>
db0a7e0
to
99e93ac
Compare
🤖 Hello there, We just published version Thanks! |
🤖 Hello there, We just published version Thanks! |
Jsonify
type utility
Fixes #7246 , #3931
type-fest
implementation is causing type errors for Remix users. Tried fixing the errors intype-fest
, but the repo setup causes some errors not to be reproducible there (and to be inconsistent with Typescript playgrounds). Additionally, there were many test cases intype-fest
forJsonify
whose "expected vs actual" I disagreed with.So for now, we can reintroduce our own implementation. Later,
type-fest
can choose which parts they wish to adopt or not.Testing strategy
Tests are collocated in the same file as the implementation and are typecheck-only tests.
TODO
useLoaderData
#3931