TypeScript按模块引入d3报错div.transition() is not a function的解决方案

一般来说,直接导入整个d3,我们会这么写:

import * as d3 from 'd3';

这样,我们就可以像在js里一样,使用熟悉的d3.select了。

但是因为不想一次性导入整个d3给项目增加大小,所以我就对d3进行了按模块导入:

import * as d3 from 'd3-selection';

这个其实也不影响select,但是因为我想给一个div增加transition的效果,就写了这么一段代码:

div.transition()
    .duration(500)
    .style('opacity', 0.9);

这个看起来是没啥问题的,但是使用的时候控制台就会报错div.transition() is not a function。上网查了一下,有很多人说升级d3的版本,但是我用的是最新的5.x,而且transition方法是在d3-selection这个模块里的:

declare module 'd3-selection' {
    interface Selection<GElement extends BaseType, Datum, PElement extends BaseType, PDatum> {
        transition(name?: string): Transition<GElement, Datum, PElement, PDatum>;
    }
}

找了很长时间,后来发现,事实上transition方法是通过d3-transition这个模块挂载到selection上的,并不属于d3-selection这个模块本身。我们可以看看d3的源码(省略了无关的部分):

// node_modules/d3-transition/src/selection/index.js
import {selection} from "d3-selection";
import selection_transition from "./transition.js";

selection.prototype.transition = selection_transition;

所以,如果直接导入d3-selection,是肯定找不到这个方法的。解决方案很简单,就是添加一个依赖,导入这个包:

import * as d3 from 'd3-selection';
import 'd3-transition';

但是,为什么会有这种误导呢,是d3写错了吗?再仔细看看package.json:

"devDependencies": {
    "@types/d3": "^5.7.2"
}

原因就在这里了。因为导入的是整个d3的类型声明,他默认我已经导入了全部的依赖,所以才会把transition方法放到Selection接口里。如果我们看一下d3-selection模块的类型声明(node_modules/@types/d3-selection/index.d.ts),就会发现,里面并没有transition方法。

所以,不仅仅在导入依赖的时候要正确导入,而且在node_modules里的依赖也要正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值