Skip to content
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

Explore type coercion for records. #5721

Merged
merged 1 commit into from
Apr 12, 2023
Merged

Conversation

cristianoc
Copy link
Collaborator

@cristianoc cristianoc commented Oct 3, 2022

The proposed PR extends type coercion ":>" in ReScript to record types, allowing you to:

  • Coerce a mandatory field to an optional one.
  • Omit fields in the target type.

Notice you can coerce a type to another identically defined one. This can be useful e.g. with React V4 components, where each one defines its own type for props.

To see an example, we have the following record types:

type r1 = {a: option<int>, b: int}
type r2 = {a?: int, b: int}
type r3 = {a?: int}
type r4 = {}
  1. Coerce a mandatory field to an optional one:
let _ = (x: r1) => (x :> r2) // Convert a from mandatory to optional
  1. Omit fields in the target type:
let _ = (x: r2) => (x :> r3) // Can omit field
let _ = (x: r1) => (x :> r3) // Omit field and convert from mandatory to optional
let _ = (x: r3) => (x :> r4) // Omit everything

However, you cannot coerce an optional field to a mandatory one, as seen in the commented line:

// let _ = (x: r2) => (x :> r1) can't turn an optional field to a mandatory one

@cristianoc cristianoc added this to the v11.0 milestone Oct 3, 2022
@cristianoc cristianoc marked this pull request as draft October 3, 2022 12:19
@cristianoc cristianoc mentioned this pull request Oct 25, 2022
3 tasks
@cristianoc cristianoc force-pushed the type_coercion_records branch 2 times, most recently from 37ea7b6 to 8bdce36 Compare April 12, 2023 03:04
@cristianoc cristianoc marked this pull request as ready for review April 12, 2023 03:26
Rough initial version.
Error messages do not explain why sub-typing fails.
@cristianoc cristianoc force-pushed the type_coercion_records branch from 8bdce36 to aeaf061 Compare April 12, 2023 03:27
@cristianoc cristianoc requested review from cknitt and zth April 12, 2023 03:28
Copy link
Collaborator

@zth zth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love that the actual added code to support this is just a couple of lines.

A few additional things I thought about:

  • when documenting this we should make sure to make explicit that this is just at the runtime level. Meaning coercing a record into a record with fewer fields, all fields from the source records are still present in runtime, but not at the type level
  • double check the error messages

@cristianoc
Copy link
Collaborator Author

Perhaps add an explanation of what type coercion is, in the docs. Then just refer to it.

Notice we can also add type coercions for variants now that the runtime representation does not have any surprises (such as special casing when there's only one case with payload).

@cristianoc
Copy link
Collaborator Author

For example you could take a known variant and type coerce into one with an additional unknown case, to be fed into a function that expects unknown as possible input.
Or play the usual subclasses games with Eg 2 vs 3 cases.

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

Successfully merging this pull request may close these issues.

3 participants