This happens because omit has very few constraints on its return type, and it returns {} by default. Take a look at the definitions for omit if you want to dig into this:
interface LoDashStatic {
omit<TResult extends {}, T extends {}>(
object: T,
...predicate: (StringRepresentable|StringRepresentable[])[]
): TResult;
}
This says that omit has two generic parameters (TResult and T, which are both at least {}). It also has one required parameter (object), and 0 or more predicates (strings, more or less). The generic parameter T is the type of its input, and TResult is the overall return type of the function.
When you don't specify generic parameters, TypeScript infers them. These parameters aren't related to each other though, or much else, so it's hard to do that accurately. It can infer T: it's the type of the parameter it's given. For TResult though, it's got nothing. If you call the function and immediately use the value, in some cases that's enough for inference to work out what the function is expected to return (so what TResult is), but in your case it isn't, so it's inferred as {}.
Once you've actually called omit in your code, you then try to assign that {} to ITest, which isn't definitely safe - it's possible to get an empty object which doesn't have an a property, and this wouldn't be correct.
You have a two options to sort this out:
Use a type assertion: const expected = <ITest> omit(foo, 'b')
Here you're telling the compiler that you're sure this is an ITest. It'll allow that (and give expected an ITest type), as long as it's possible you're correct - you don't have to be definitely correct, as you do with the plain assignment.
Specify the return type for the function by providing the generic parameters that omit uses explicitly: const expected = omit<ITest, {}>(foo, 'b').
Currently these parameters are being inferred automatically, but these type definitions don't have any way to derive the 'correct' type ("the type of foo, but without 'a'"), so you end up with the most general return type possible: {}. If you explicitly set those generics, you can control this more closely. You only really want to specify one generic parameter here (the return type), but you can't do that sadly: you have to either specify both, or neither.
Personally I'd use a type assertion, but I think from this point it comes down to a matter of personal taste.