diff --git a/src/index.test.ts b/src/index.test.ts index daea0194..00917c97 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -649,6 +649,33 @@ describe('stringify & parse', () => { }, }, + 'works with NaN and Infinity in Float64Array, issue #292': { + input: { + a: new Float64Array([NaN, 0, NaN, 1]), + b: new Float64Array([Infinity, -Infinity, NaN, 0]), + c: new Float32Array([NaN, Infinity, -Infinity]), + }, + output: { + a: ['NaN', 0, 'NaN', 1], + b: ['Infinity', '-Infinity', 'NaN', 0], + c: ['NaN', 'Infinity', '-Infinity'], + }, + outputAnnotations: { + values: { + a: [['typed-array', 'Float64Array']], + b: [['typed-array', 'Float64Array']], + c: [['typed-array', 'Float32Array']], + }, + }, + customExpectations: (value: any) => { + expect(Number.isNaN(value.a[0])).toBe(true); + expect(Number.isNaN(value.a[2])).toBe(true); + expect(value.b[0]).toBe(Infinity); + expect(value.b[1]).toBe(-Infinity); + expect(Number.isNaN(value.b[2])).toBe(true); + }, + }, + 'works for undefined, issue #48': { input: undefined, output: null, diff --git a/src/transformer.ts b/src/transformer.ts index c48a015e..69dedef1 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -224,7 +224,15 @@ const constructorToName = [ const typedArrayRule = compositeTransformation( isTypedArray, v => ['typed-array', v.constructor.name], - v => [...v], + v => [...v].map(n => { + // Handle special float values that JSON.stringify converts to null + if (typeof n === 'number') { + if (Number.isNaN(n)) return 'NaN'; + if (n === Infinity) return 'Infinity'; + if (n === -Infinity) return '-Infinity'; + } + return n; + }), (v, a) => { const ctor = constructorToName[a[1]]; @@ -232,7 +240,15 @@ const typedArrayRule = compositeTransformation( throw new Error('Trying to deserialize unknown typed array'); } - return new ctor(v); + // Convert string representations back to special float values + const values = v.map((n: number | string): number => { + if (n === 'NaN') return NaN; + if (n === 'Infinity') return Infinity; + if (n === '-Infinity') return -Infinity; + return n as number; + }); + + return new ctor(values as number[]); } );