Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ isBoolean(value);
| `@IsISO8601(options?: IsISO8601Options)` | Checks if the string is a valid ISO 8601 date format. Use the option strict = true for additional checks for a valid date. |
| `@IsJSON()` | Checks if the string is valid JSON. |
| `@IsJWT()` | Checks if the string is valid JWT. |
| `@IsObject()` | Checks if the object is valid Object (null, functions, arrays will return false). |
| `@IsObject(options: IsObjectOptions)` | Checks if the object is valid Object (null, arrays will return false). |
| `@IsNotEmptyObject()` | Checks if the object is not empty. |
| `@IsLowercase()` | Checks if the string is lowercase. |
| `@IsLatLong()` | Checks if the string is a valid latitude-longitude coordinate in the format lat, long. |
Expand Down
20 changes: 16 additions & 4 deletions src/decorator/typechecker/IsObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,36 @@ import { buildMessage, ValidateBy } from '../common/ValidateBy';

export const IS_OBJECT = 'isObject';

/**
* Options to be passed to IsObject decorator.
*/
export interface IsObjectOptions {
excludeFunctions?: boolean;
}

/**
* Checks if the value is valid Object.
* Returns false if the value is not an object.
*/
export function isObject<T = object>(value: unknown): value is T {
return value != null && (typeof value === 'object' || typeof value === 'function') && !Array.isArray(value);
export function isObject<T = object>(value: unknown, options: IsObjectOptions = {}): value is T {
return (
value != null &&
(typeof value === 'object' || (typeof value === 'function' && !options.excludeFunctions)) &&
!Array.isArray(value)
);
}

/**
* Checks if the value is valid Object.
* Returns false if the value is not an object.
*/
export function IsObject(validationOptions?: ValidationOptions): PropertyDecorator {
export function IsObject(options: IsObjectOptions = {}, validationOptions?: ValidationOptions): PropertyDecorator {
return ValidateBy(
{
name: IS_OBJECT,
constraints: [options],
validator: {
validate: (value, args): boolean => isObject(value),
validate: (value, args): boolean => isObject(value, args?.constraints[0]),
defaultMessage: buildMessage(eachPrefix => eachPrefix + '$property must be an object', validationOptions),
},
},
Expand Down
9 changes: 9 additions & 0 deletions test/functional/validation-functions-and-decorators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,11 @@ describe('IsObject', () => {
someProperty: object;
}

class ExcludeFunctionsTestClass {
@IsObject({ excludeFunctions: true })
someProperty: object;
}

it('should not fail if validator.validate said that its valid', () => {
return checkValidValues(new MyClass(), validValues);
});
Expand All @@ -3192,6 +3197,10 @@ describe('IsObject', () => {
const message = 'someProperty must be an object';
return checkReturnedError(new MyClass(), invalidValues, validationType, message);
});

it('should fail if excludeFunctions is true and the value is a function', () => {
return checkInvalidValues(new ExcludeFunctionsTestClass(), [function () {}]);
});
});

describe('IsNotEmptyObject', () => {
Expand Down