Поле payload может быть скалярного типа Int или String.
когда я пишу это как тип объединения:
const schema = `
input QuickReply {
content_type: String
title: String
payload: Int | String
image_url: String
}
`
У меня ошибка:
GraphQLError: Syntax Error GraphQL request (45:18) Expected Name, found |
44: title: String
45: payload: Int | String
^
46: image_url: String
Похоже, что GraphQL не поддерживает скалярный тип объединения.
Итак, как я могу решить эту ситуацию?


Скаляры не могут использоваться как часть объединений, поскольку согласно спецификации объединения специально «представляют объект, который может быть одним из списка типов объектов GraphQL». Вместо этого вы можете использовать собственный скаляр. Например:
const MAX_INT = 2147483647
const MIN_INT = -2147483648
const coerceIntString = (value) => {
if (Array.isArray(value)) {
throw new TypeError(`IntString cannot represent an array value: [${String(value)}]`)
}
if (Number.isInteger(value)) {
if (value < MIN_INT || value > MAX_INT) {
throw new TypeError(`Value is integer but outside of valid range for 32-bit signed integer: ${String(value)}`)
}
return value
}
return String(value)
}
const IntString = new GraphQLScalarType({
name: 'IntString',
serialize: coerceIntString,
parseValue: coerceIntString,
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return coerceIntString(parseInt(ast.value, 10))
}
if (ast.kind === Kind.STRING) {
return ast.value
}
return undefined
}
})
Этот код эффективно комбинирует поведение для типов Int и String, при этом по-прежнему применяя диапазон для 32-разрядных целых чисел со знаком. Однако у вас может быть любое поведение приведения типа, которое вы хотите. Ознакомьтесь с исходный код, чтобы увидеть, как работают встроенные скаляры, или эта статья, чтобы узнать больше о том, как работают пользовательские скаляры.
Обратите внимание, что если вы пытаетесь вернуть один из нескольких скаляров для поля выход, можно использовать объединение для типа родитель для достижения аналогичного результата. Например, это невозможно:
type Post {
content: String | Int
}
но вы можете сделать следующее:
type PostString {
content: String
}
type PostInt {
content: Int
}
union Post = PostString | PostInt
Звучит как хорошее решение для смешивания нескольких скаляров. В моем случае есть ответ задачи, и он может быть либо скалярным (Int, String), либо типом объекта. Я мог бы использовать скалярный JSON вместо типов объектов, но JSON не проверяет внутренние поля и не может гарантировать, что они находятся в ответе, а не в качестве опции. Итак, я столкнулся с той же проблемой, но похоже, что это решение не сработает для чего-то вроде: union = String | Int | MyTypeOne | MyTypeTwo ... MyTypeTen. Какие-либо предложения?
@Mihail Вместо использования скаляра JSON вы все равно можете создать собственный скаляр с проверкой, специфичной для вашего варианта использования. В остальном, если вы используете это для типа вывода, вы можете использовать объединение для родительского типа как описано выше.
Супер интересный ответ !!! Я нигде не нашел такого подходящего примера ....