I am in the following situation:
interface Rec {
key: string;
children: this[];
}
type Recursive<D extends string> = {
[K in D]: string;
} & Rec;
type FlattenRecursive =
<D extends string, R extends Recursive<D>>(rs: R[]) => Omit<R, "children">[]
const flatten: FlattenRecursive =
rs => rs.flatMap(r => flatten(r.children))
I expect the recursive call to the flatten function to be inferred as flatten<D, R> instead of the current <string, R>. Therefore, I'm forced to explicitly annotate the type arguments when calling it:
type RValueAnimal = Recursive<"value"> & { animal: string }
const rvalues: RValueAnimal[] = [
// ...
]
flatten(rvalues) // <- error
flatten<"value", RValueAnimal>(rvalues)
How can I solve this problem?
Dcannot be inferred fromR; instead it falls back tostring. You should removeDentirely and refactor to express the constraint you care about purely in terms ofR. Maybe like this? Does that address your question fully? If so I'll write up an answer; if not, what am I missing?D. I think I could writeR extends Recursive<any>orR extends Recursive<never>given thatDseems to be contravariant (side question: I am not sure why it is not invariant given its recursive use).