I have a database model (Mongo) and an API model (Apollo). These two are identical except for a 'start' field which is resolved from a string to an object. How to exclude the 'start' field from being inherited or somehow override it?
class Start {
iso: string;
local: string;
}
// database model
class BaseThing {
// a lot of other fields
start: string; // < - - I don't want to have 'any' type here
}
// API model
class Thing extends BaseThing {
// a lot of other fields [inherited]
start: Start; // < - - how to exclude start from being inherited or somehow override it?
}
This isn't really good practice: subclasses inherit superclass properties and methods. If inheritance isn't desired, it's possible one might really want composition instead of class hierarchies, but that's out of scope for this question. Let's show how to get the behavior you're looking for and then remind everyone at the end that it could lead to weird issues.
If you want to prevent the compiler from seeing the
BaseThingconstructor as constructing something with astartproperty, you can use a type assertion to widen the type ofBaseThingfrom (something like)new () => BaseThingtonew () => Omit<BaseThing, "start">using theOmit<T, K>utility type:That's a bit ugly looking, but it works. The compiler sees
Thingas inheriting everything exceptstartfromBaseThing.If you do this kind of thing often, you could think of refactoring this widening into a helper function like:
where
which can be hidden in a library somewhere.
PLEASE NOTE that, depending on the implementation of the base class, this sort of intentional widening and then incompatible re-narrowing could lead to trouble. Imagine something like this:
So far so good. But then:
This fails because the base class's
method()depends onvalbeing astringand not anything else. Pseudo-subclasses that changevalto some non-stringtype will be unhappy at runtime unless they also overridemethod(). So anyone who does something like this which intentionally circumvents type safety warnings should take care not to trip over the part of the rug under which the problem has been swept.Playground link to code