Skip to content

Commit

Permalink
fix the object constraint for NonEmptyObject<T> (#336)
Browse files Browse the repository at this point in the history
* fix the object constraint for `NonEmptyObject<T>`

* refactor test for `NonEmptyObject`  to new file

* docs: 📄 update changeset

Update .changeset/great-hounds-brush.md

Co-authored-by: Alexey Berezin <2991847+Beraliv@users.noreply.github.com>
  • Loading branch information
ajitjha393 and Beraliv committed Nov 19, 2022
1 parent 66a6169 commit 4c45165
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-hounds-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ts-essentials": patch
---

Improve the object constraint for `NonEmptyObject<T>` to not allow primitives
2 changes: 1 addition & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ type DeepModify<T> =
/** Remove keys with `never` value from object type */
export type NonNever<T extends {}> = Pick<T, { [K in keyof T]: T[K] extends never ? never : K }[keyof T]>;

export type NonEmptyObject<T extends {}> = keyof T extends never ? never : T;
export type NonEmptyObject<T extends AnyRecord> = keyof T extends never ? never : T;

export type NonEmptyArray<T> = [T, ...T[]];

Expand Down
10 changes: 1 addition & 9 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
DictionaryValues,
Merge,
MergeN,
NonEmptyObject,
NonNever,
noop,
PickProperties,
Expand Down Expand Up @@ -44,6 +43,7 @@ import {
ArrayOrSingle,
IsAny,
NonEmptyArray,
Primitive,
} from "../lib";
import { TsVersion } from "./ts-version";
import { ComplexNestedPartial, ComplexNestedRequired } from "./types";
Expand Down Expand Up @@ -832,14 +832,6 @@ function testNonNever() {
type TestB = Assert<IsExact<keyof NonNever<Mapped>, "foo" | "bar">>;
}

function testNonEmptyObject() {
type ObjectWithKeys = { foo: string; bar: number; xyz: undefined };
type EmptyObject = {};

type TestA = Assert<IsExact<NonEmptyObject<ObjectWithKeys>, ObjectWithKeys>>;
type TestB = Assert<IsExact<NonEmptyObject<EmptyObject>, never>>;
}

function testNonEmptyArray() {
type Cases<T> = [
Assert<IsExact<NonEmptyArray<T>, [T, ...T[]]>>,
Expand Down
22 changes: 22 additions & 0 deletions test/non-empty-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AssertTrue as Assert, IsExact } from "conditional-type-checks";
import { NonEmptyObject } from "../lib";

function testNonEmptyObject() {
type ObjectWithKeys = { foo: string; bar: number; xyz: undefined };
type EmptyObject = {};

type Cases = [
Assert<IsExact<NonEmptyObject<ObjectWithKeys>, ObjectWithKeys>>,
Assert<IsExact<NonEmptyObject<EmptyObject>, never>>,
// Works with Wrapper Object Types
Assert<IsExact<NonEmptyObject<String>, String>>,
Assert<IsExact<NonEmptyObject<Number>, Number>>,
Assert<IsExact<NonEmptyObject<Boolean>, Boolean>>,
// @ts-expect-error
Assert<IsExact<NonEmptyObject<string>, string>>, // Will Not work as T is a Primitive
// @ts-expect-error
Assert<IsExact<NonEmptyObject<number>, number>>, // Will Not work as T is a Primitive
// @ts-expect-error
Assert<IsExact<NonEmptyObject<undefined>, number>>, // Will Not work as T is a Primitive
];
}

0 comments on commit 4c45165

Please sign in to comment.