Within my codebase, I've established a straightforward generic interface W
. Extending this interface are two more interfaces - T
and N
, each adding a property type
that can be utilized in a tagged union scenario:
interface W<V> {
value: V
}
interface T extends W<string> {
type: 'text'
}
interface N extends W<number> {
type: 'number'
}
In addition to these, there's another type called D
, representing the union of T
and N
. Furthermore, there exists a function named getValue
, which takes as input an argument adhering to the generic wrapper type and simply returns its encapsulated value.
type D = T | N
const getValue = <V extends any>(
wrapper: W<V>
): V => {
return wrapper.value
}
The dilemma arises when attempting to use a value of type D
with the getValue
function. The TypeScript compiler raises an error stating that
the argument of type 'D' is not assignable to parameter of type 'W<string>'
:
// Typecasting is necessary here to prevent the tsc from assuming that d is solely of type 'T'
const d: D = { value: 'hello', type: 'text'} as D
// Why isn't 'D' recognized as a valid type for getValue? Shouldn't the inferred return type simply be 'string | number'?
getValue(d)
I attempted to adjust the typing of the getValue
function so that the TypeScript compiler could infer that the return type would indeed be string | number
if a value of type D
was passed in. My expectation is for the compiler to deduce the return type successfully without raising any complaints when d
is provided.