Skip to content

Commit

Permalink
feat(utils): implement type guard for nullable object props
Browse files Browse the repository at this point in the history
  • Loading branch information
matejchalk committed Dec 16, 2024
1 parent e5f743a commit c3fc549
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 13 deletions.
4 changes: 2 additions & 2 deletions packages/plugin-lighthouse/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { CliFlags } from 'lighthouse';
import type { ExcludeNullFromPropertyTypes } from '@code-pushup/utils';
import type { ExcludeNullableProps } from '@code-pushup/utils';

export type LighthouseOptions = ExcludeNullFromPropertyTypes<
export type LighthouseOptions = ExcludeNullableProps<
Partial<
Omit<
CliFlags,
Expand Down
17 changes: 9 additions & 8 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ export {
truncateText,
truncateTitle,
} from './lib/formatting.js';
export {
formatGitPath,
getGitRoot,
guardAgainstLocalChanges,
safeCheckout,
toGitPath,
} from './lib/git/git.js';
export {
getCurrentBranchOrTag,
getHashFromTag,
Expand All @@ -54,10 +47,18 @@ export {
getSemverTags,
type LogResult,
} from './lib/git/git.commits-and-tags.js';
export {
formatGitPath,
getGitRoot,
guardAgainstLocalChanges,
safeCheckout,
toGitPath,
} from './lib/git/git.js';
export { groupByStatus } from './lib/group-by-status.js';
export {
isPromiseFulfilledResult,
isPromiseRejectedResult,
hasNoNullableProps,
} from './lib/guards.js';
export { logMultipleResults } from './lib/log-results.js';
export { link, ui, type CliUi, type Column } from './lib/logging.js';
Expand Down Expand Up @@ -114,7 +115,7 @@ export {
type CliArgsObject,
} from './lib/transform.js';
export type {
ExcludeNullFromPropertyTypes,
ExcludeNullableProps,
ExtractArray,
ExtractArrays,
ItemOrArray,
Expand Down
8 changes: 8 additions & 0 deletions packages/utils/src/lib/guards.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { ExcludeNullableProps } from './types.js';

export function isPromiseFulfilledResult<T>(
result: PromiseSettledResult<T>,
): result is PromiseFulfilledResult<T> {
Expand All @@ -9,3 +11,9 @@ export function isPromiseRejectedResult(
): result is PromiseRejectedResult {
return result.status === 'rejected';
}

export function hasNoNullableProps<T extends object>(
obj: T,
): obj is ExcludeNullableProps<T> {
return Object.values(obj).every(value => value != null);
}
24 changes: 23 additions & 1 deletion packages/utils/src/lib/guards.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { describe } from 'vitest';
import { isPromiseFulfilledResult, isPromiseRejectedResult } from './guards.js';
import {
hasNoNullableProps,
isPromiseFulfilledResult,
isPromiseRejectedResult,
} from './guards.js';

describe('promise-result', () => {
it('should get fulfilled result', () => {
Expand All @@ -20,3 +24,21 @@ describe('promise-result', () => {
expect(isPromiseRejectedResult(result)).toBe(true);
});
});

describe('hasNoNullableProps', () => {
it('should return true if object prop values are neither null nor undefined', () => {
expect(hasNoNullableProps({ a: 42, b: 'foo', c: {}, d: [] })).toBe(true);
});

it('should return false if some prop is null', () => {
expect(hasNoNullableProps({ x: 42, y: null })).toBe(false);
});

it('should return false if some prop is set to undefined', () => {
expect(hasNoNullableProps({ x: undefined })).toBe(false);
});

it('should return true for empty object', () => {
expect(hasNoNullableProps({})).toBe(true);
});
});
4 changes: 2 additions & 2 deletions packages/utils/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type ExcludeNullFromPropertyTypes<T> = {
[P in keyof T]: Exclude<T[P], null>;
export type ExcludeNullableProps<T> = {
[P in keyof T]: NonNullable<T[P]>;
};

export type ItemOrArray<T> = T | T[];
Expand Down

0 comments on commit c3fc549

Please sign in to comment.