-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Statically typing cells? #2205
Comments
@thedavidprice mind tagging the relevant team members? I know you mentioned several people have been thinking about this but I didn't catch their names. |
looping in @peterp @dac09 @Tobbe Also, @Krisztiaan might be interested as well Thanks all! |
This is a great suggestion, and definitely helps clear up the idea in my head. Using your idea of generics in withCell, What if we did something like this? // We type the QUERY here!
// Look below
const QUERY: Document<{comments: string[]}> = gql`
query CommentsQuery($postId: Int!) {
comments(postId: $postId) {
// ...
}
}
`
const Loading = () => <div>Loading...</div>
const Empty = () => <div>No comments yet</div>
const Failure = ({ error }) => <div>Error: {error.message}</div>
const Success = ({ comments }) =>
comments.map((comment) => <Comment key={comment.id} comment={comment} />) And when when we process the file with the babel plugin we add the new line automatically, but slightly differently. // Generated code ->
// Something to dig out the type from inside Document
type GqlReturnType = xxx
// This is pseudo type code, have to look up the syntax for "if afterQuery exists"
type GqlReturnOrAfterQuery = ReturnType<afterQuery> || GqlReturnType<Query>
export default withCell<GqlReturnOrAfterQuery>{ QUERY, Success, Failure, Empty, Loading }) The key is that the type detection is handled automatically, with no need to add the extra line. Just throwing my idea out there, not sure whether its a solid plan, happy to hear otherwise. Also: what this might let us do is use type generators https://www.graphql-code-generator.com/docs/plugins/typescript (not tried it yet). |
@dac09 if the |
You're right... this is why you don't try to figure out solutions late at night. I'll have a think tomorrow! |
I really like this proposal. I think it's a solid way forward for our Typescript story. Removes a bit of magic, at the cost of a single line, and remains backwards compatible (until we deprecate the babel plugin). I think we should go for it! |
@corbt , what are your thoughts on what the generators should produce? |
Correct me if I'm wrong, but I think |
You're definitely not wrong. Even react themselves use that naming convention. See |
Yeah, It doesn't make as much semantic sense with cells though -- if I call That said, naming is not a hill I want to die on. 😄 |
I'd vote to use this syntax for generated TS cells. No opinion on whether to use it for generated JS cells. |
This PR is the first step towards implementing redwoodjs#2205. It allows users to declare the prop types their cells expect. It also renames `withCell` to `createCell`, for the reasons I outlined in redwoodjs#2205 (comment). `createCell` feels like a more parsimonious name to me but I can back that change out if others disagree. It appears that the babel transform for wrapping cells already checks for a default export and bails out if one exists, so this shouldn't require any changes there. The major remaining task is updating the cell generator to add a `export default createCell` line at the end of each cell in Typescript. I'd appreciate more input on whether this is a change we're fine making on both the TS and JS sides, or whether we'll need two templates. Do we have multiple templates anywhere else?
Haha, that's a funny way to put it ⚔️ ⛰️ And I'm fine with |
This PR is the first step towards implementing redwoodjs#2205. It allows users to declare the prop types their cells expect. It also renames `withCell` to `createCell`, for the reasons I outlined in redwoodjs#2205 (comment). `createCell` feels like a more parsimonious name to me but I can back that change out if others disagree. It appears that the babel transform for wrapping cells already checks for a default export and bails out if one exists, so this shouldn't require any changes there. The major remaining task is updating the cell generator to add a `export default createCell` line at the end of each cell in Typescript. I'd appreciate more input on whether this is a change we're fine making on both the TS and JS sides, or whether we'll need two templates. Do we have multiple templates anywhere else?
Totally, a very valid argument, let's go with |
@corbt are you taking the lead on the code for this? Let me know if you need any support. |
So I thought a little bit more about this with a fresh mind, I think I was conflating two difference aspects of the types: and it looks like there's no resistance towards adding a new line (optionally), and I don't really have a strong opinion on this, so happy to continue as is. |
This is something really important to me too, but yeah, I think it can be tackled separately. :) |
Thanks for the mention. As a part of #1878 I have also taken steps to add type safety to the Without any major change, just drilling a generic for the data through the current solution would be enough to secure I may have not given this thread a thorough enough read, if so, call me out on it, but solving for this problem seems like a quick non-breaking change PR in a couple LOC. Here's the weird experiment I have stashed from the other PR (not correct, just for entertainment): |
What a beautiful issue number, #2222, an alternative direction to go, with regards to fixing the |
* Static typing for cells This PR is the first step towards implementing #2205. It allows users to declare the prop types their cells expect. It also renames `withCell` to `createCell`, for the reasons I outlined in #2205 (comment). `createCell` feels like a more parsimonious name to me but I can back that change out if others disagree. It appears that the babel transform for wrapping cells already checks for a default export and bails out if one exists, so this shouldn't require any changes there. The major remaining task is updating the cell generator to add a `export default createCell` line at the end of each cell in Typescript. I'd appreciate more input on whether this is a change we're fine making on both the TS and JS sides, or whether we'll need two templates. Do we have multiple templates anywhere else? * Add notice about 'withCell' deprecation for 'createCell.' Co-authored-by: Peter Pistorius <peter.pistorius@gmail.com>
Hey everyone!
I had a proposal on statically typing cells, and would love feedback. I know there are a lot of tradeoffs involved and other folks have been thinking about this!
Essentially, my proposal involves making
withCellHOC
part of the public API and letting users explicitly call it to create cell components. There would need to be a few modifications towithCellHOC
for full typing support -- most importantly, it should be possible to tell it which props the cell expects. A basic sketch of the updated type signature would look something like this. (Note that I've renamedwithCellHOC
tocreateCell
since I think that's a clearer name.)Consider the following cell, adapted from the tutorial:
The same cell using
createCell
would be defined as follows:This does add one line of code, of course. But in return, cells and their props can be strongly typed, which is a big win!
This also doesn't have to be mutually exclusive with the existing
export const ...
syntax. The babel transform could just check whether there's a default export, and skip applying itself in that case.The text was updated successfully, but these errors were encountered: