Proposal: typesafe tagged template literals

To have proper interop with JS, there is a need for binding to tagged template literals. I especially run into this with graphql-ppx because most GraphQL libraries use tagged template literals to represent GraphQL operations and fragments. We found a hacky way to bind to them that involves require and %raw but it’s not ideal.

I think there could be quite nice way to bind to them. The below could be the function signature:

let graphql: (array(string), @variadic array('a)) => 'b

And the following syntax:

graphql`
  query {
    ...MyFragment
  }
  ${myFragment}
`

would be the same in ReScript and JS. It can even be supported in non-es6 by just calling the function.

The “only” language feature we need is the @variadic annotation in the last argument. Not sure if that is feasible, and it might be only implementable with an external (which would actually be quite ok, because normally we would only use template literals to bind to external libraries).

Thoughts about this?

2 Likes

Perhaps the ... operator can help to spread the arguments. If the function has a variadic annotation ReScript can compile the JS with that operator. The operator can also be used on the function implementation side.

Example here:

let bla = (first, ...rest) => [first, rest];

bla(1,2,3) // => [1, [2,3]]
bla(1, ...[2,3]) // => [1, [2,3]]
1 Like

Can u use a trivial tagged template literal so I can have a better idea what u want to do

I provided the trivial GraphQL example, what more would you like to see?

1 Like

for exemple, using (the famous) styled-components package:

import styled from "styled-components"

const BeautifulWrapper = styled.div`
  display: flex;
  background: ${({ bg }) => bg};
`;

...

<BeautifulWrapper bg="red">Hello</BeautifulWrapper>

It’s very difficult to map that kind of tag template functions in rescript.
It will be great to have something like

@react.component
module BeautifulWrapper =  styled.div`
  display: flex;
  background: ${(~bg) => bg};
`;
1 Like