The following throws an error:
Types of property 'type' are incompatible. Type 'MyEnum' is not assignable to type 'MyEnum.C | MyEnum.D'.
I understand what it means, but cannot find a good solution to it.
enum MyEnum {
B,
C,
D,
}
interface MyInterface {
type: MyEnum
otherData: string
}
function func1(data: MyInterface): void {
if (
data.type === MyEnum.C ||
data.type === MyEnum.D
) {
func2(data) // throws an error
}
}
function func2(
data: Omit<MyInterface, 'type'> & {
type:
| MyEnum.C
| MyEnum.D
},
): void {}
How to tell typescript I'm going to work with data whose key type is either MyEnum.C
or MyEnum.D
?
CodePudding user response:
You could cast data
to the required type:
enum MyEnum {
A, B, C, D
}
interface MyInterface {
type: MyEnum;
}
type MyInterfaceCD = Omit<MyInterface, 'type'> & {
type:
| MyEnum.C
| MyEnum.D
};
function func1(data: MyInterface): void {
if (
data.type === MyEnum.C ||
data.type === MyEnum.D
) {
func2(data as MyInterfaceCD) // throws an error
}
}
function func2(
data: Omit<MyInterface, 'type'> & {
type:
| MyEnum.C
| MyEnum.D
},
): void {}
CodePudding user response:
You can change move the condition to a function with return type which check for a type. like this:
enum MyEnum {
A,B,C,D
}
interface MyInterface {
type: MyEnum;
}
interface OmittedInterface extends Omit<MyInterface, 'type'> {
type: MyEnum.C | MyEnum.D
}
function isOmittedInterface(data: MyInterface): data is OmittedInterface {
return data.type === MyEnum.C || data.type === MyEnum.D
}
function func1(data: MyInterface): void {
if (isOmittedInterface(data)) {
func2(data);
}
}
function func2(
data: Omit<MyInterface, 'type'> & {
type:
MyEnum.C
| MyEnum.D
},
): void {}
The return type of isOmittedInterface
will make typescript look at the type as OmittedInterface if its return true