relay
relay copied to clipboard
Enhancement of the customScalars format for typescript
As of today, the customScalars format is straightforward, just a string / string mapping, and then limit the use of custom scalars to native types. The customScalars format can be enhanced to support more complex types: A proposal can be:
const customScalars = {
MyType: {
type: 'MyType',
module: '../myModule'
},
MySimpleString: 'String'
}
this will add
import { MyType } from '../myModule';
in the generated file. Do you agree with that format? I can do a PR on the relay-tools/relay-compiler-language-typescript repo.
(When I suggested opening this ticket, I meant it to be agnostic of programming language. The TS plugin simply follows what Relay does.)
ok, the typing language agnostic view of the proposal: customScalars is an object with keys as custom type name, and their associated value is either a string or an object with a 'type' key and eventually other keys:
const customScalars = {
MyType: {
type: 'MyType',
// other props specific to a typing language
module: '../myModule',
},
MySimpleString: 'String',
// or the equivalent declaration:
MySimpleString: {
type: 'String',
}
}
this would be really great. To add to @pebeka proposal, to make it truly agnostic, I think it's necessary to provide a map for each target language. something like:
customScalars: {
MyType: {
flow: X,
typeScript: Y,
}
}
how X and Y look is actually specified by the plugin itself and relay-compiler remains unopinionated (for example, one implementation could be @pebeka's proposal, another could be a simple string that is eval
ed, etc).
It'd be sort of weird for types to have different names in Flow and TS, esp. if any of them are runtime types, no?
not different names, different definitions, eg typescript's Record
is different from whatever flow has
a proposal for the proposal: allow a custom scalar to have a serialized & a parsed value.
For example, a custom DateTime
will come back as a string
in the response payload. However, if I use DateTime
as an argument, I'd like it to be a Date
. Apologies if this is already possible, just haven't figured out how to do it yet!
I'm using io-ts right now to serialize and deserialize at runtime the iso-strings received from my DB to Moment objects.
export const DateTime = new t.Type<moment.Moment, string>(
'DateTime',
(mixed): mixed is moment.Moment => moment.isMoment(mixed),
(mixed, context) =>
pipe(
t.string.validate(mixed, context),
either.chain(str => {
const instance = moment(str)
return instance.isValid() ? t.success(instance) : t.failure(str, context)
})
),
instance => instance.toISOString()
)
For now, I just map the payloads and responses to fit my needs but having custom scalars would be so much more convenient.
I would really like to have the ability to automatically decode payloads and encode responses when they are flagged with a specific GraphQL scalar by providing the appropriate handler to Relay Compiler.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
What's the reason this was marked as "wontfix"? CC @mofeiZ
This issue appears to be a duplicate of https://github.com/facebook/relay/issues/91 (91! 🤯)
I think this issue could be closed. More complex custom scalars are already supported. Configuration:
https://github.com/facebook/relay/blob/dec019d3290233e134b603124001814a77832271/scripts/config.tests.json#L23-L25
Implementation:
https://github.com/facebook/relay/blob/2768c3ea12668c5bf23d47d51515bd3939f9543f/packages/relay-runtime/mutations/tests/OpaqueScalarType.js#L15-L30
@mrtnzlml Do you have any more information about it? I can't find any documentation about it at all :eyes:
In particular: how do I need to define the custom scalar type? What are the requirements? Is it possible to parse DateTimes to Date
objects (one of the main use cases of this feature request).
@LukasKalbertodt, I do not have more info. But maybe @captbaritone?
We added config-file-define TS/Flow types for custom scalars recently but have not yet documented them. They get specified in the compiler config. For now checking the Rust structs for the config file is your best bet to understand how they are used.
They do now allow you custom transformation (serialize/deserialize) functions.
That said, I think @alunyov recently mentioned he had done some investigation into how/if that might be possible.
@captbaritone @alunyov Is this supported in new compiler ?
@captbaritone I think you've got a misleading typo there 😅
They do ~now~ not allow you custom transformation (serialize/deserialize) functions.
Is custom serialize/deserialize investigation @alunyov conducted public, and is it something you would accept contributions on?
^ would love full custom scalar support / happy to contribute as well, I think ideally you would be able to just use GraphQL custom scalar types from graphql-js (example)
This would be tremendously useful for me as well. Currently doing a lot of manual deserializing and useMemo.
I would also love to hear some feedback about this feature. It doesn't seem to be in latest Relay compiler.