This is the only solution I can think of (Thanks to the comment of @Fahd Lihidheb)
type NotEmpty<T> = keyof T extends never ? never : T
function createTest<T extends {[key: string]: any}>(test: NotEmpty<T>): T {
return test
}
const obj = createTest({}) // error
const anotherObj = createTest({ something: "thing" }) // works
I don't think it is possible with just a type definition. We have to use a factory method instead so we can infer the type of T and check if any keys exist.
Typescript non empty object with unknown properties - Stack Overflow
Empty object type is not working
TypeScript empty object for a typed variable - Stack Overflow
Check if specific object is empty in typescript
This is the only solution I can think of (Thanks to the comment of @Fahd Lihidheb)
type NotEmpty<T> = keyof T extends never ? never : T
function createTest<T extends {[key: string]: any}>(test: NotEmpty<T>): T {
return test
}
const obj = createTest({}) // error
const anotherObj = createTest({ something: "thing" }) // works
I don't think it is possible with just a type definition. We have to use a factory method instead so we can infer the type of T and check if any keys exist.
I stumbled upon a possible answer when working on something else.
type NonEmptyObj<T extends Record<string, unknown>> = T extends Record<string, never> ? never : T;
This relies on Record<string, never> which defines an empty object. We check if T never extends an empty object.
Utilizing this test would look something like this:
function someFunction<T extends Record<string, unknown>>(foo: NonEmptyObject<T>) { ... }
TS playground link
Should you do this? Probably not. The error provided by this typing is quite unhelpful and the possible use-case very niche.
Caveats
Here are two worthy caveats from the comments.
Either you want user to be of type
User | {}orPartial<User>, or you need to redefine theUsertype to allow an empty object. Right now, the compiler is correctly telling you that user is not a User. –jcalz
I don't think this should be considered a proper answer because it creates an inconsistent instance of the type, undermining the whole purpose of TypeScript. In this example, the property
Usernameis left undefined, while the type annotation is saying it can't be undefined. –Ian Liu Rodrigues
Answer
One of the design goals of TypeScript is to "strike a balance between correctness and productivity." If it will be productive for you to do this, use Type Assertions to create empty objects for typed variables.
type User = {
Username: string;
Email: string;
}
const user01 = {} as User;
const user02 = <User>{};
user01.Email = "[email protected]";
Here is a working example for you.

An empty object can be written as Record<string,never>, so effectively your type for user is either an empty object or a User
const user : User | Record<string, never> = {};
Use Object.keys(obj).length to check if it is empty.
Output : 3
Source: Object.keys()
You can use Object.keys like this:
class Brand { }
const brand = new Brand();
if (Object.keys(brand).length === 0) {
console.log("No properties")
}
If you want to check if the object has at least one non-null, non-undefined property:
- Get all the values of the object in an array using
Object.values() - Check if at least one of has value using
some
const hasValues =
(obj) => Object.values(obj).some(v => v !== null && typeof v !== "undefined")
class Brand { }
const brand = new Brand();
if (hasValues(brand)) {
console.log("This won't be logged")
}
brand.name = null;
if (hasValues(brand)) {
console.log("Still no")
}
brand.name = "Nike";
if (hasValues(brand)) {
console.log("This object has some non-null, non-undefined properties")
}
I would like to create a type where it accepts all string except empty string. So buttonAriaLabel = "I am button" is acceptable, but if empty string is passed in buttonAriaLabel = " ", this will generate type error like "empty string is not assignable to type..." . I tried following technique (s: string): s is Excluse<typeof s, ' '> but it doesn't work at all. What are the techniques available to achieve this?
type NonEmptyString = {
(s: string): s is Exclude<typeof s, ''>;
};
export interface IButton {
// ... other properties
buttonAriaLabel: NonEmptyString;
}
// Desired Result
const button: IButton = {
// ... other properties
buttonAriaLabel: 'Close', // Valid non-empty string
};
const invalidButton: IButton = {
// ... other properties
buttonAriaLabel: '' ", // TypeScript error: Type " " is not assignable to type 'NonEmptyString'.
};
A feature request for allowing you to just check array.length > 0 to guard against empty arrays, microsoft/TypeScript#38000, was declined as being too complex. Essentially you cannot usually simply check length in TypeScript to convince the compiler about the availability of properties at given numeric keys.
You can define a non-empty array type like this:
type NonEmptyArray<T> = [T, ...T[]];
const okay: NonEmptyArray<number> = [1, 2];
const alsoOkay: NonEmptyArray<number> = [1];
const err: NonEmptyArray<number> = []; // error!
This is due to support added in TS 3.0 for rest elements in tuple types. I'm not sure what your use case is... It's probably more annoying to use that type than you expect, though:
function needNonEmpty(arr: NonEmptyArray<number>) {}
function needEmpty(arr: []) {}
declare const bar: number[];
needNonEmpty(bar); // error, as expected
if (bar.length > 0) {
needNonEmpty(bar); // ugh, still error!
}
If you want a length check to work, you'll need to use something like a user-defined type guard function, but it's still annoying to use:
function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> {
return arr.length > 0;
}
if (isNonEmptyArray(bar)) {
needNonEmpty(bar); // okay
} else {
needEmpty(bar); // error!! urgh, do you care?
}
I've also wondered about this and came up with a different solution:
type NonEmptyArray<T> = T[] & { 0: T };