Reputation: 53
Is there a way to define a type that allows for a object with any properties, but enforces having at least 1 (unknown) property?
// this does not work
type Test = {
[key: string]: any
}
const obj: Test = {} // this should give an error
const anotherObj: Test = { something: "thing" } // this should work
Upvotes: 3
Views: 1817
Reputation: 53
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>) { ... }
Should you do this? Probably not. The error provided by this typing is quite unhelpful and the possible use-case very niche.
Upvotes: 0
Reputation: 23825
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.
Upvotes: 3