تایپاسکریپت - خطاهای نوع برای d3js در انگولار (آخرین نسخه)


من متوجه شدهام که هنگامی که d3js را با Angular (Typescript) استفاده میکنم، خطاهای زیادی از نوع وجود دارد. به عنوان مثال نمیتوانم قطعه کد زیر را کار کنم

svg.call(d3.zoom().on('zoom', () => {
      g.attr('transform', d3.events.transform);
    }));

پرتابها

S2345: Argument of type 'ZoomBehavior<Element, unknown>' is not assignable to parameter of type '(selection: Selection<BaseType, unknown, HTMLElement, any>, ...args: any[]) => void'.   Types of parameters 'selection' and 'selection' are incompatible.     Type 'Selection<BaseType, unknown, HTMLElement, any>' is not assignable to type 'Selection<Element, unknown, any, any>'.       Types of property 'select' are incompatible.         Type '{ <DescElement extends BaseType>(selector: string): Selection<DescElement, unknown, HTMLElement, any>; <DescElement extends BaseType>(selector: null): Selection<null, undefined, HTMLElement, any>; <DescElement extends BaseType>(selector: ValueFn<...>): Selection<...>; }' is not assignable to type '{ <DescElement extends BaseType>(selector: string): Selection<DescElement, unknown, any, any>; <DescElement extends BaseType>(selector: null): Selection<null, undefined, any, any>; <DescElement extends BaseType>(selector: ValueFn<...>): Selection<...>; }'.           Types of parameters 'selector' and 'selector' are incompatible.             Types of parameters 'groups' and 'groups' are incompatible.               Type 'BaseType[] | ArrayLike<BaseType>' is not assignable to type 'Element[] | ArrayLike<Element>'.                 Type 'BaseType[]' is not assignable to type 'Element[] | ArrayLike<Element>'.                   Type 'BaseType[]' is not assignable to type 'Element[]'.                     Type 'BaseType' is not assignable to type 'Element'.                       Type 'null' is not assignable to type 'Element'.

همچنین، خطای دیگری این است که d3.events تعریف نشده است.

نکتهای دارید که چطور این را کار بیندازم؟ چندین نمونه کد وجود دارد که به دلیل خطاهای نوع اصلاً کار نمیکنند. حتی با استفاده از @ts-ignore هم حل نمیشوند.

بهروزرسانی: پس از استفاده از راهنمای مهاجرت از نسخه v5 به v6، هاندلر زوم دیگر خطایی ایجاد نمیکند

const zoom = d3.zoom().on('zoom', ({transform}, d) => {
   g.attr('transform', transform);
});

اما هنوز خطای نوع وجود دارد وقتی سعی میکنیم آن را اینطور صدا بزنیم

svg.call(zoom)

پاسخ شماره ۱

درباره 'کد d3.event تعریف نشده است':

اگر با خطای نوع مواجه شوید که d3.event تعریف نشده است، اما d3.event هنگام اجرای برنامه کار میکند، این بدان معناست که بسته @types/d3 در نسخهای است که با d3 v6 مطابقت دارد، در حالی که بسته d3 خود در d3 v5 است. این خطا به دلیل تغییراتی بین d3 v5 و v6 رخ میدهد، که شامل حذف d3.event است.

شما میتوانید نسخههای تایپها را در صفحه npm مشاهده کنید. آنها تقریباً با نسخههای d3 مطابقت دارند، بنابراین نسخهای که به دنبال آن هستید @types/[email است.

درباره خطای نوع:

اگر نوع انتخاب را مشخص نکنید، به طور پیشفرض به Selection<BaseType, unknown, HTMLElement, any> تنظیم میشود. با این حال، d3.zoom به طور پیشفرض روی ZoomBehavior<Element, unknown> قرار دارد. مشکل این است که تایپاسکریپت اعلان میدهد که BaseType و Element با هم سازگار نیستند.

برای رفع آن، میتوانید انتخاب svg و بزرگنمایی را با جنریکهای صریح تعریف کنید:

const svg = d3.select<SVGSVGElement, unknown>(...);
const zoom = d3.zoom<SVGSVGElement, unknown>() [...];

svg.call(zoom);

خط اول میگوید شما در حال انتخاب یک SVGSVGElement هستید (نوع عنصر <svg>) که داده آن unknown است. خط دوم میگوید که بزرگنمایی بر روی یک انتخاب از SVGSVGElement که همچنین نوع داده آن unknown است، فراخوانی خواهد شد.

حالا جنریکهای هر دو zoom و svg مطابقت دارند و متد .call سازگار خواهد بود. این یک codesandbox است که آن را نشان میدهد.