The reason behind this issue is that the function omit
has very few restrictions on its return type, and by default it returns an empty object {}
. To understand this better, refer to the definitions for omit:
interface LoDashStatic {
omit<TResult extends {}, T extends {}>(
object: T,
...predicate: (StringRepresentable|StringRepresentable[])[]
): TResult;
}
This definition states that omit has two generic parameters (TResult
and T
, both of which are at least {}
). It requires one parameter (object
) and zero or more predicate
s (mostly strings). The generic parameter T represents the type of its input, while TResult signifies the overall return type of the function.
In TypeScript, when you do not specify generic parameters, the compiler infers them. However, these parameters are independent of each other, making accurate inference challenging. While T
can be inferred as the type of the given parameter, TResult
might remain ambiguous. In cases where the inferred value after function execution does not help determine TResult
, it defaults to {}
.
Subsequently, assigning this generic object {}
to ITest
may not always be safe as an empty object lacking the required property a
could be returned.
To address this issue, you have two solutions:
Use a type assertion:
const expected = <ITest> omit(foo, 'b')
By employing a type assertion, you are confirming to the compiler that the result is indeed of type ITest
. The compiler accepts this validation as long as it seems plausible rather than absolutely certain, in contrast to direct assignment.
Specify the return type explicitly by providing the generic parameters used by omit
:
const expected = omit<ITest, {}>(foo, 'b')
.
Currently, the automatic inference of these parameters fails to determine the correct type ("type of foo without 'a'") resulting in the most generalized return type {}
. By explicitly setting the generics, you gain more control over the return type. Ideally, only one generic parameter (return type) should be specified, but unfortunately, both must be declared or omitted together.
While I personally recommend using a type assertion, the choice between approaches ultimately boils down to individual preference.