I am trying to use a third party TypeScript module and am having trouble creating an abstract type that other types can extend.
The base type Animal will be either Mammal, Reptile, or Amphibian.
The action method from a third party ActionModule will take a slightly different type as input for each action, but I wanted to create a base type that can be given for the generic U from ActionModule for my ACTIONS type.
Here's what I have so far, which doesn't seem to work (getting an error saying types are incompatible).
type Animal = Mammal | Reptile | Amphibian;
type Mammal = {
name: string,
furColor: number
};
type Reptile = {
name: string,
scaleCount: number
};
type Amphibian = {
name: string;
};
// Third-party module
interface ActionModule<T = {}, U = {}> {
description: string,
action: (args: Arguments<U>) => void
}
const ACTIONS: {
[key: string]: ActionModule<{}, Animal>
} = {
actionOne: {
description: '',
action: (args: Arguments<Mammal>) => {},
},
actionTwo: {
description: '',
action: (args: Arguments<Reptile>) => {},
},
actionThree: {
description: '',
action: (args: Arguments<Amphibian>) => {},
}
}
TLDR:
type Animal = Mammal & Reptile & Amphibian
Longer answer:
Expanding and simplyfying your code we get:
action: (args: Mammal | Reptile | Amphibian) => void
Which means that the argument of this function can take any of the types specified in the union. So to each implementation of the interface must support all the union types.
Instead you can merge the interfaces which means that the method may support one of the types. More specificlly it will allow an object that has at least common properties of the interfaces.