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 evaled, 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.
Most helpful comment
a proposal for the proposal: allow a custom scalar to have a serialized & a parsed value.
For example, a custom
DateTimewill come back as astringin the response payload. However, if I useDateTimeas an argument, I'd like it to be aDate. Apologies if this is already possible, just haven't figured out how to do it yet!