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
TypeScript empty object for a typed variable - Stack Overflow
Empty object type is not working
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'.
};