I use d3 with types definition from @types/d3. I have a method that operates with the union of Selection and Transition. The argument could be either one. Both Selection and Transition types have the selectAll method.
But when I try to apply selectAll to the union, I get the following error:
This expression is not callable. Each member of the union type '{ (): Selection<null, undefined, BaseType, unknown>; (selector: null): Selection<null, undefined, BaseType, unknown>; (selector: undefined): Selection<...>; <DescElement extends BaseType, OldDatum>(selector: string): Selection<...>; <DescElement extends BaseType, OldDatum>(selector: ValueFn<...>): Selection<...>; } ...' has signatures, but none of those signatures are compatible with each other.
Here is an example of code that gives this error:
/* Definitions from @types/d3 */
export type BaseType = Element | Document | Window | null;
export type ValueFn<T extends BaseType, Datum, Result> = (this: T, datum: Datum, index: number, groups: T[] | ArrayLike<T>) => Result;
export interface Transition<GElement extends BaseType, Datum, PElement extends BaseType, PDatum> {
selectAll<DescElement extends BaseType, OldDatum>(selector: string): Transition<DescElement, OldDatum, GElement, Datum>;
selectAll<DescElement extends BaseType, OldDatum>(selector: ValueFn<GElement, Datum, DescElement[] | ArrayLike<DescElement>>): Transition<DescElement, OldDatum, GElement, Datum>;
}
export interface Selection<GElement extends BaseType, Datum, PElement extends BaseType, PDatum> {
selectAll(): Selection<null, undefined, GElement, Datum>;
selectAll(selector: null): Selection<null, undefined, GElement, Datum>;
selectAll(selector: undefined): Selection<null, undefined, GElement, Datum>;
selectAll<DescElement extends BaseType, OldDatum>(selector: string): Selection<DescElement, OldDatum, GElement, Datum>;
selectAll<DescElement extends BaseType, OldDatum>(selector: ValueFn<GElement, Datum, DescElement[] | ArrayLike<DescElement>>): Selection<DescElement, OldDatum, GElement, Datum>;
}
/* My code */
function myFunc(maybeTransition: Selection<BaseType, unknown, BaseType, unknown> | Transition<BaseType, unknown, BaseType, unknown>) {
const texts = maybeTransition.selectAll('text'); // ERROR: This expression is not callable.
// do something with texts
}
So the questions are:
- Is it possible to fix this issue using existing type definitions?
- If the issue can't be fixed without changing Transition or Selection interfaces, how should it be?