Skip to content

Commit f8e8f90

Browse files
committed
Make coercion code more explicit.
1 parent 1a5e611 commit f8e8f90

File tree

2 files changed

+46
-33
lines changed

2 files changed

+46
-33
lines changed

src/type/__tests__/serialization-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('Type System: Scalar coercion', () => {
6969
'Int cannot represent non-integer value: Infinity',
7070
);
7171
expect(() => GraphQLInt.serialize([5])).to.throw(
72-
'Int cannot represent an array value: [5]',
72+
'Int cannot represent non-integer value: [5]',
7373
);
7474
});
7575

@@ -98,7 +98,7 @@ describe('Type System: Scalar coercion', () => {
9898
'Float cannot represent non numeric value: ""',
9999
);
100100
expect(() => GraphQLFloat.serialize([5])).to.throw(
101-
'Float cannot represent an array value: [5]',
101+
'Float cannot represent non numeric value: [5]',
102102
);
103103
});
104104

src/type/scalars.js

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ const MAX_INT = 2147483647;
2222
const MIN_INT = -2147483648;
2323

2424
function serializeInt(value: mixed): number {
25-
if (Array.isArray(value)) {
26-
throw new TypeError(
27-
`Int cannot represent an array value: ${inspect(value)}`,
28-
);
25+
let num = value;
26+
if (typeof value === 'string' && value !== '') {
27+
num = Number(value);
28+
} else if (typeof value === 'boolean') {
29+
return value ? 1 : 0;
2930
}
30-
const num = Number(value);
31-
if (value === '' || !isInteger(num)) {
31+
32+
if (!isInteger(num)) {
3233
throw new TypeError(
3334
`Int cannot represent non-integer value: ${inspect(value)}`,
3435
);
@@ -74,13 +75,14 @@ export const GraphQLInt = new GraphQLScalarType({
7475
});
7576

7677
function serializeFloat(value: mixed): number {
77-
if (Array.isArray(value)) {
78-
throw new TypeError(
79-
`Float cannot represent an array value: ${inspect(value)}`,
80-
);
78+
let num = value;
79+
if (typeof value === 'string' && value !== '') {
80+
num = Number(value);
81+
} else if (typeof value === 'boolean') {
82+
return value ? 1 : 0;
8183
}
82-
const num = Number(value);
83-
if (value === '' || !isFinite(num)) {
84+
85+
if (!isFinite(num)) {
8486
throw new TypeError(
8587
`Float cannot represent non numeric value: ${inspect(value)}`,
8688
);
@@ -120,14 +122,16 @@ function serializeString(value: mixed): string {
120122
value && typeof value.valueOf === 'function' ? value.valueOf() : value;
121123
// Serialize string, boolean and number values to a string, but do not
122124
// attempt to coerce object, function, symbol, or other types as strings.
123-
if (
124-
typeof result !== 'string' &&
125-
typeof result !== 'boolean' &&
126-
!isFinite(result)
127-
) {
128-
throw new TypeError(`String cannot represent value: ${inspect(result)}`);
129-
}
130-
return String(result);
125+
if (typeof result === 'string') {
126+
return result;
127+
}
128+
if (typeof result === 'boolean') {
129+
return result ? 'true' : 'false';
130+
}
131+
if (isFinite(result)) {
132+
return result.toString();
133+
}
134+
throw new TypeError(`String cannot represent value: ${inspect(value)}`);
131135
}
132136

133137
function coerceString(value: mixed): string {
@@ -153,12 +157,15 @@ export const GraphQLString = new GraphQLScalarType({
153157
});
154158

155159
function serializeBoolean(value: mixed): boolean {
156-
if (typeof value !== 'boolean' && !isFinite(value)) {
157-
throw new TypeError(
158-
`Boolean cannot represent a non boolean value: ${inspect(value)}`,
159-
);
160+
if (typeof value === 'boolean') {
161+
return value;
160162
}
161-
return Boolean(value);
163+
if (isFinite(value)) {
164+
return value !== 0;
165+
}
166+
throw new TypeError(
167+
`Boolean cannot represent a non boolean value: ${inspect(value)}`,
168+
);
162169
}
163170

164171
function coerceBoolean(value: mixed): boolean {
@@ -185,17 +192,23 @@ function serializeID(value: mixed): string {
185192
// to represent an object identifier (ex. MongoDB).
186193
const result =
187194
value && typeof value.valueOf === 'function' ? value.valueOf() : value;
188-
if (typeof result !== 'string' && !isInteger(result)) {
189-
throw new TypeError(`ID cannot represent value: ${inspect(value)}`);
195+
if (typeof result === 'string') {
196+
return result;
190197
}
191-
return String(result);
198+
if (isInteger(result)) {
199+
return String(result);
200+
}
201+
throw new TypeError(`ID cannot represent value: ${inspect(value)}`);
192202
}
193203

194204
function coerceID(value: mixed): string {
195-
if (typeof value !== 'string' && !isInteger(value)) {
196-
throw new TypeError(`ID cannot represent value: ${inspect(value)}`);
205+
if (typeof value === 'string') {
206+
return value;
207+
}
208+
if (isInteger(value)) {
209+
return value.toString();
197210
}
198-
return String(value);
211+
throw new TypeError(`ID cannot represent value: ${inspect(value)}`);
199212
}
200213

201214
export const GraphQLID = new GraphQLScalarType({

0 commit comments

Comments
 (0)