I have the following interfaces:
export interface Base {
a: string;
b: string;
}
export interface Foo extends Base {
c: string[];
type: 'foo';
}
export interface Bar extends Base {
c: string;
type: 'bar';
}
From these interfaces I define the union type MyType
in this way:
export type MyType = Foo | Bar;
The type MyType
is thus inferred as:
{
a: string;
b: string;
c: string | string[];
type: 'foo' | 'bar';
}
which is the intended behavior. If I define a function like:
function testFunction1(param: MyType): MyType {
return param;
}
It works fine, but when I replace MyType
with Omit<MyType, 'b'>
the compiler doesn't want to accept the code in any way. Example:
function testFunction2(param: Omit<MyType, 'b'>): MyType {
return {...param, b: 'a'};
}
It returns the following error:
Type '{ b: string; c: string | string[]; type: "foo" | "bar"; a: string; }' is not assignable to type 'MyType'.
Type '{ b: string; c: string | string[]; type: "foo" | "bar"; a: string; }' is not assignable to type 'Bar'.
Types of property 'c' are incompatible. Type 'string | string[]' is not assignable to type 'string'. Type 'string[]' is not assignable to type 'string'.
Even if I'm sure that the returned value is compatible with MyType
, since I'm changing a property defined in Base
. How can I combine Omit
and union types?
Note:
I'm trying to refine a type in a large codebase, for this reason, I don't want to force the type with a type assertion everywhere (e.g. return {...} as MyType
). In the codebase there's a large use of Omit<>
and when I refactored MyType
in this way everything stopped working.