Skip to content

Commit

Permalink
fix(assert): make generic isPlainObject works with partial
Browse files Browse the repository at this point in the history
  • Loading branch information
belgattitude committed May 3, 2024
1 parent d2adb5d commit fd1d0c5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-pants-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@httpx/assert": patch
---

isPlainObject works with partial types
4 changes: 4 additions & 0 deletions .github/workflows/ci-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
- name: 🕵️ Typecheck
run: yarn workspaces foreach -v --worktree --from '@examples/*' run typecheck

- name: 🕵️ Typecheck (no typescript path aliases)
run: yarn workspaces foreach -v --worktree --from '@examples/*' run typecheck-no-paths


- name: 🔬 Lint
run: yarn workspaces foreach -v --worktree --from '@examples/*' run lint

Expand Down
28 changes: 22 additions & 6 deletions packages/assert/src/__tests__/object.types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { assertType } from 'vitest';

import { assertPlainObject } from '../object.asserts';
import { isPlainObject } from '../object.guards';
import type { PlainObject } from '../object.types';
import type {
PlainObject,
PlainObjectDeepPartialUnknown,
} from '../object.types';

describe('object types tests', () => {
describe('isPlainObject', () => {
Expand Down Expand Up @@ -37,24 +40,33 @@ describe('object types tests', () => {
assertType<unknown>(po?.deep?.yes);
});

it('should return a type PlainObject with shaped values 2', () => {
it('should return a type PlainObject with shaped non null | undefined values', () => {
type DeepCustomType = {
id: number;
requiredDeep: {
id: number;
};
data?: {
test: string[];
attributes?: {
url?: string | null;
caption?: string | null;
alternativeText?: string | null;
} | null;
} | null;
};
const po: DeepCustomType = {
const po = {
id: 1,
requiredDeep: {
id: 1,
},
data: {
attributes: {
url: 'cool',
caption: 'test',
},
},
};
} as unknown;
const typed = isPlainObject<DeepCustomType>(po);
// eslint-disable-next-line jest/no-conditional-in-test
if (!typed) {
Expand All @@ -63,8 +75,12 @@ describe('object types tests', () => {
assertType<PlainObject>(po);
assertType<PlainObject<DeepCustomType>>(po);
assertType<Record<string | number, unknown>>(po);
assertType<DeepCustomType>(po);
assertType<string | undefined | null>(po.data?.attributes?.url);
assertType<PlainObjectDeepPartialUnknown<DeepCustomType>>(po);
expectTypeOf(po?.data).not.toBeUnknown();
expectTypeOf(po?.data?.attributes).not.toBeUnknown();
expectTypeOf(po?.data?.attributes?.url).toBeUnknown();
expectTypeOf(po?.id).toBeUnknown();
expectTypeOf(po?.requiredDeep?.id).toBeUnknown();
});
});
});
4 changes: 2 additions & 2 deletions packages/assert/src/object.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export type PlainObjectDeepPartialUnknown<T> = {
[P in keyof T]?: T[P] extends object
? PlainObjectDeepPartialUnknown<T[P]>
[P in keyof T]?: NonNullable<T[P]> extends Record<string, unknown>
? PlainObjectDeepPartialUnknown<NonNullable<T[P]>>
: unknown;
};

Expand Down

0 comments on commit fd1d0c5

Please sign in to comment.