Skip to content

Commit

Permalink
chore(ui,ui-react-core): Add type guard utils (#3291)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioanabrooks authored Jan 27, 2023
1 parent 8c62114 commit 9ce2d01
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/sixty-buttons-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@aws-amplify/ui-react-core': patch
'@aws-amplify/ui': patch
---

chore(ui,ui-react-core): Add type guard utils
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
getSortedFormFields,
UnverifiedContactMethods,
getActorContext,
isString,
} from '@aws-amplify/ui';
import isString from 'lodash/isString';

import { areEmptyArrays, areEmptyObjects } from '../../../utils';
import { AuthenticatorLegacyField, AuthenticatorLegacyFields } from '../types';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConsoleLogger as Logger } from '@aws-amplify/core';
import isString from 'lodash/isString';
import { isString } from '@aws-amplify/ui';

import { MessageAction } from '../types';

Expand Down
3 changes: 2 additions & 1 deletion packages/react-core/src/hooks/useHasValueUpdated.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isUndefined } from '@aws-amplify/ui';

import usePreviousValue from './usePreviousValue';
import isUndefined from 'lodash/isUndefined';

export default function useHasValueUpdated<Value>(
value: Value,
Expand Down
6 changes: 3 additions & 3 deletions packages/react-core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import isEmpty from 'lodash/isEmpty';
import isObject from 'lodash/isObject';
import isString from 'lodash/isString';

import { isObject, isString } from '@aws-amplify/ui';

function isEmptyArray<T>(value: T): boolean {
return Array.isArray(value) && isEmpty(value);
Expand All @@ -11,7 +11,7 @@ export function areEmptyArrays<T>(...values: T[]): boolean {
}

function isEmptyObject<T>(value: T): boolean {
return isObject(value) && !Array.isArray(value) && isEmpty(value);
return isObject(value) && isEmpty(value);
}

export function areEmptyObjects<T>(...values: T[]): boolean {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './i18n';
export * from './machines';
export * from './theme';
export * from './types';
export * from './utils';
3 changes: 1 addition & 2 deletions packages/ui/src/theme/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import has from 'lodash/has';
import isObject from 'lodash/isObject';
import isString from 'lodash/isString';
import kebabCase from 'lodash/kebabCase';

// internal style dictionary function
import usesReference from 'style-dictionary/lib/utils/references/usesReference';

import { isObject, isString } from '../utils';
import {
DesignToken,
ShadowValue,
Expand Down
61 changes: 61 additions & 0 deletions packages/ui/src/utils/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { isObject, isString, isUndefined } from '..';

describe('isObject', () => {
it('should return `true` for objects', () => {
expect(isObject(new Number(0))).toStrictEqual(true);
expect(isObject(new String(''))).toStrictEqual(true);
expect(isObject(new Date())).toStrictEqual(true);
expect(isObject(new Error())).toStrictEqual(true);
expect(isObject({})).toStrictEqual(true);
expect(isObject({ test: 1 })).toStrictEqual(true);
expect(isObject(Object(false))).toStrictEqual(true);
expect(isObject(Object(0))).toStrictEqual(true);
expect(isObject(Object('test'))).toStrictEqual(true);
});

it('should return `false` for non-objects', () => {
expect(isObject(null)).toStrictEqual(false);
expect(isObject(undefined)).toStrictEqual(false);
expect(isObject(true)).toStrictEqual(false);
expect(isObject(0)).toStrictEqual(false);
expect(isObject('test')).toStrictEqual(false);
expect(isObject([1, 2, 3])).toStrictEqual(false);
expect(isObject(() => {})).toStrictEqual(false);
});
});

describe('isString', () => {
it('should return `true` for strings', () => {
expect(isString('')).toStrictEqual(true);
expect(isString('test')).toStrictEqual(true);
expect(isString(new String('test'))).toStrictEqual(true);
});

it('should return `false` for non-strings', () => {
expect(isString(null)).toStrictEqual(false);
expect(isString(undefined)).toStrictEqual(false);
expect(isString(true)).toStrictEqual(false);
expect(isString(0)).toStrictEqual(false);
expect(isString([1, 2, 3])).toStrictEqual(false);
});
});

describe('isUndefined', () => {
it('should return `true` for undefined values', function () {
expect(isUndefined(undefined)).toStrictEqual(true);
expect(isUndefined(void 0)).toStrictEqual(true);
});

it('should return `false` for non-undefined values', function () {
expect(isUndefined(null)).toStrictEqual(false);
expect(isUndefined(true)).toStrictEqual(false);
expect(isUndefined('')).toStrictEqual(false);
expect(isUndefined(0)).toStrictEqual(false);
expect(isUndefined([1, 2, 3])).toStrictEqual(false);
expect(isUndefined(new Number(0))).toStrictEqual(false);
expect(isUndefined(new String(''))).toStrictEqual(false);
expect(isUndefined(new Date())).toStrictEqual(false);
expect(isUndefined(new Error())).toStrictEqual(false);
expect(isUndefined({})).toStrictEqual(false);
});
});
35 changes: 35 additions & 0 deletions packages/ui/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Checks if `value` is an Object (non-primitive, non-array, non-function)
* Will return false for Arrays and functions
*
*
* @param {unknown} value The value to check
* @returns {boolean} Returns `true` if `value` is an object, `false` otherwise
*/
export function isObject(value: unknown): value is object {
return value != null && !Array.isArray(value) && typeof value === 'object';
}

/**
* Checks if `value` is a string primitive or object
*
* @param {unknown} value The value to check
* @returns {boolean} Returns `true` if `value` is a string, `false` otherwise
*/
export function isString(value: unknown): value is string {
return (
typeof value === 'string' ||
(typeof value === 'object' &&
Object.prototype.toString.call(value) === '[object String]')
);
}

/**
* Checks if `value` is undefined
*
* @param {unknown} value The value to check
* @returns {boolean} Returns `true` if `value` is undefined, `false` otherwise
*/
export function isUndefined(value: unknown): value is undefined {
return value === undefined;
}

0 comments on commit 9ce2d01

Please sign in to comment.