I want to pass typed data from a database into a generic transformer function. It seems like the best way to accomplish this in Typescript is via a discriminating union. But, this requires a discriminant property. Is there a way to auto-generate the discriminant? Or, is there a way to write a generic transformer function using something other than a discriminated union? I'm open to other solutions besides the kind I'm suggesting below.
type DB1 = {
id: string
one: string
}
type DB2 = {
id: string
two: string
}
type One = {
id: number
one: string
}
type Two = {
id: number
two: string
}
function transformer(x: DB1): One
function transformer(x: DB2): Two
function transformer(x: DB1 | DB2): One | Two {
switch (x.kind) { // There is no x.kind!
case 'DB1': return db1ToOne(x)
case 'DB2': return db2ToTwo(x)
}
}
The challenge is easily discriminating between DB1 and DB2. Since they come from the database library directly, I do not manually instantiate the types myself, and so I do not have an opportunity "on creation" of the objects to manually include a discriminant property. I also don't really like the idea of "hacking" into DB1 and DB2 and tacking on a discriminant just before I pass it to the transformer.
Is there a way to discriminate between these types so that the transformer works the way I want it to?
(Also, since this solution is supposed to scale to many types, don't assume there is anything else besides a potential discriminant property which can otherwise differentiate between types.)