Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Update v4 spec about sharing props type #701

Merged
merged 5 commits into from
Oct 27, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions cli/JSXV4.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,36 @@ let p: A.props<_> = {x: "x", y: "y"}
<A x="X" {...p}>
<A {...p} {...p1}>
```

### Shared props type (new feature)

V4 introduces support to set a props type from the outside. It allows sharing of the props type between components.

```rescript
type sharedProps<'a> = {x: 'a, y: string}

module A = {
@react.component(:sharedProps<'a>)
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you clarify in the text above what's the role of <'a>. Does the name 'a matter, or is it only used to specify the number of type arguments?

Copy link
Member Author

@mununki mununki Oct 26, 2022

Choose a reason for hiding this comment

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

It is just telling the number of type arguments are available. Better to remove it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I understand: or can be 1 zero type args, or 2 more than zero. And the user needs to specify which one is true?

Copy link
Member Author

@mununki mununki Oct 27, 2022

Choose a reason for hiding this comment

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

Sorry for making communication cost. My point was that I expected there were some use cases:

type sp1 = ...

@react.component(:sp1)
type sp2<'a> = ...

@react.component(:sp2<'a>)
// or
@react.component(:sp2<string>)
type sp3<'a, 'b, ...> = ...

@react.component(:sp3<'a, 'b, ...>)
// or
@react.component(:sp3<string, 'b, ...>)

The text is saying that the type argument(s) is available. The name of 'a nor the number of type arguments wouldn't matter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does it work also if the type definition has zero type arguments?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you mean this case:

type sp1 = ...

@react.component(:sp1)

Yes, it works. https://github.com/rescript-lang/syntax/blob/master/tests/ppx/react/expected/sharedProps.res.txt#L38

Copy link
Contributor

@cristianoc cristianoc Oct 27, 2022

Choose a reason for hiding this comment

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

I read the source code. So the number of type variables does matter. The name matters only so much as it normally matters, but not less.

So I think what's missing in the doc is one example with 0 and one with 2 type variables.

Copy link
Contributor

@cristianoc cristianoc Oct 27, 2022

Choose a reason for hiding this comment

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

One should also remark on the fact that a type called props cannot be defined in the current module or there will be a type error due to type redefinition. (It could at most be defined outside the current module)

Copy link
Member Author

Choose a reason for hiding this comment

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

One should also remark on the fact that a type called props cannot be defined in the current module or there will be a type error due to type redefinition. (It could at most be defined outside the current module)

I think this is already noted as https://github.com/rescript-lang/syntax/blob/master/cli/JSXV4.md#transformation-for-component-definition

Copy link
Member Author

@mununki mununki Oct 27, 2022

Choose a reason for hiding this comment

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

How does it look? c052cb9 1112ae6

let make = (~x, ~y) => React.string(x ++ y)
}

module B = {
@react.component(:sharedProps<'a>)
let make = (~x, ~y) => React.string(x ++ y)
}

// is transformed to
module A = {
type props<'a> = sharedProps<'a>

let make = ({x, y, _}: props<'a>) => React.string(x ++ y)
...
}

module B = {
type props<'a> = sharedProps<'a>

let make = ({x, y, _}: props<'a>) => React.string(x ++ y)
...
}
```