Skip to content

Commit

Permalink
fix(bigint): Use typeof for testing if BigInt exists
Browse files Browse the repository at this point in the history
The `if (BigInt) { … }` style does not work in browser environments that do not implement BigInt (e.g. Safari <= 13).

A `hasBigInt` flag was added and exported from `util` and uses the format of `typeof BigInt !== ‘undefined’` which should work in all environments.  All usage of `BigInt` is now guarded by an equivalent of `if (hasBigInt) {…}` to ensure it’s available before use.
  • Loading branch information
kdubb committed Jul 22, 2020
1 parent adb7bd3 commit 777dd99
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
11 changes: 6 additions & 5 deletions src/core/JsonParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getDefaultPrimitiveTypeValue,
getMetadata,
getMetadataKeys,
hasBigInt,
hasMetadata,
isClassIterable,
isConstructorPrimitiveType,
Expand Down Expand Up @@ -284,7 +285,7 @@ export class JsonParser<T> {
if (value.constructor === String) {
if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, Number)) {
value = +value;
} else if (BigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
} else if (hasBigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
value = BigInt(+value);
} else if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, Boolean)) {
if (value.toLowerCase() === 'true' || value === '1') {
Expand All @@ -298,7 +299,7 @@ export class JsonParser<T> {
} else if (value.constructor === Number) {
if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, Boolean)) {
value = !!value;
} else if (BigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
} else if (hasBigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
value = BigInt(+value);
} else if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, String)) {
// @ts-ignore
Expand All @@ -307,7 +308,7 @@ export class JsonParser<T> {
} else if (value.constructor === Boolean) {
if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, Number)) {
value = value ? 1 : 0;
} else if (BigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
} else if (hasBigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
value = BigInt(value ? 1 : 0);
} else if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, String)) {
// @ts-ignore
Expand Down Expand Up @@ -353,7 +354,7 @@ export class JsonParser<T> {
if (isSameConstructorOrExtensionOfNoObject(currentMainCreator, Map) ||
(typeof value === 'object' && !isIterableNoMapNoString(value) && currentMainCreator === Object)) {
return this.parseMapAndObjLiteral(key, value, context, globalContext);
} else if (BigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
} else if (hasBigInt && isSameConstructorOrExtensionOfNoObject(currentMainCreator, BigInt)) {
return (value != null && value.constructor === String && value.endsWith('n')) ?
// @ts-ignore
currentMainCreator(value.substring(0, value.length - 1)) :
Expand Down Expand Up @@ -459,7 +460,7 @@ export class JsonParser<T> {
(context.features.deserialization.SET_DEFAULT_VALUE_FOR_PRIMITIVES_ON_NULL ||
context.features.deserialization.SET_DEFAULT_VALUE_FOR_BOOLEAN_ON_NULL) ) {
defaultValue = getDefaultPrimitiveTypeValue(Boolean);
} else if (BigInt && currentMainCreator === BigInt &&
} else if (hasBigInt && currentMainCreator === BigInt &&
(context.features.deserialization.SET_DEFAULT_VALUE_FOR_PRIMITIVES_ON_NULL ||
context.features.deserialization.SET_DEFAULT_VALUE_FOR_BIGINT_ON_NULL) ) {
defaultValue = getDefaultPrimitiveTypeValue(BigInt);
Expand Down
5 changes: 3 additions & 2 deletions src/core/JsonStringifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
getDefaultValue,
getMetadata,
getObjectKeysWithPropertyDescriptorNames,
hasBigInt,
hasMetadata,
isConstructorPrimitiveType,
isIterableNoMapNoString,
Expand Down Expand Up @@ -337,7 +338,7 @@ export class JsonStringifier<T> {

value = this.stringifyJsonFormatClass(value, context);

if (BigInt && isSameConstructorOrExtensionOfNoObject(value.constructor, BigInt)) {
if (hasBigInt && isSameConstructorOrExtensionOfNoObject(value.constructor, BigInt)) {
return value.toString() + 'n';
} else if (value instanceof RegExp) {
const replacement = value.toString();
Expand Down Expand Up @@ -565,7 +566,7 @@ export class JsonStringifier<T> {
(context.features.serialization.SET_DEFAULT_VALUE_FOR_PRIMITIVES_ON_NULL ||
context.features.serialization.SET_DEFAULT_VALUE_FOR_BOOLEAN_ON_NULL) ) {
defaultValue = getDefaultPrimitiveTypeValue(Boolean);
} else if (BigInt && currentMainCreator === BigInt &&
} else if (hasBigInt && currentMainCreator === BigInt &&
(context.features.serialization.SET_DEFAULT_VALUE_FOR_PRIMITIVES_ON_NULL ||
context.features.serialization.SET_DEFAULT_VALUE_FOR_BIGINT_ON_NULL) ) {
defaultValue = getDefaultPrimitiveTypeValue(BigInt);
Expand Down
6 changes: 6 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,3 +953,9 @@ export const castObjLiteral = (target: any, value: any): any => {
*/
export const sortMappersByOrder = <T>(mappers: CustomMapper<T>[]): CustomMapper<T>[] =>
mappers.sort((a, b) => a.order - b.order > 0 ? 1 : -1);


/**
* Flag for testing if BigInt is supported
*/
export const hasBigInt = typeof BigInt !== 'undefined';

0 comments on commit 777dd99

Please sign in to comment.