在TypeScript模块中扩展AngularJS时jQuery集成问题求助
这个问题我之前也碰到过,核心原因是:当你用ES模块语法局部导入jquery和angular时,两者都是模块作用域内的局部变量,AngularJS初始化时不会去模块内部找jQuery,而是默认使用内置的JQLite,而JQLite并没有scrollTop()这类jQuery特有的方法,所以才会抛出类型错误。
下面给你几个可行的解决办法,按需选择:
方法1:手动将jQuery暴露到全局(适合模块优先的项目)
在导入AngularJS之前,把局部导入的jQuery挂载到window全局对象上,让AngularJS初始化时能检测到它:
// 先导入jQuery import * as $ from 'jquery'; // 将jQuery暴露到全局(TypeScript需要断言window类型,避免类型报错) (window as any).jQuery = $; (window as any).$ = $; // 再导入AngularJS,此时它会自动使用全局的jQuery import * as angular from 'angular'; export default ['$window', function($window) { // 现在angular.element返回的是jQuery对象,不再是JQLite let position = angular.element($window).scrollTop(); }];
原理
AngularJS启动时会检查全局的window.jQuery变量,如果存在就会用它替换内置的JQLite,这样所有angular.element()调用都会返回jQuery实例,支持完整的jQuery API。
方法2:使用全局脚本加载(适合传统非模块项目)
如果你的项目还保留传统的脚本加载方式,可以直接在HTML中按顺序加载jQuery和AngularJS,不用在TypeScript中导入它们:
<!-- 先加载jQuery,暴露全局$和jQuery --> <script src="path/to/jquery.min.js"></script> <!-- 再加载AngularJS,它会自动识别全局的jQuery --> <script src="path/to/angular.min.js"></script> <!-- 最后加载你的TypeScript编译后的脚本 --> <script src="dist/your-app.js"></script>
然后在TypeScript中直接使用全局变量,同时配置tsconfig.json引入类型声明,让TypeScript识别全局的$和angular:
{ "compilerOptions": { // 引入jquery和angular的类型定义 "types": ["jquery", "angular"], "target": "ES5" // 根据你的项目需求调整 } }
TypeScript代码可以这样写:
// 不用导入$和angular,直接使用全局变量 export default ['$window', function($window) { let position = angular.element($window).scrollTop(); }];
方法3:用打包工具自动注入全局变量(比如Webpack)
如果使用Webpack这类模块打包工具,可以通过ProvidePlugin自动将jQuery注入到全局,无需手动修改代码:
在Webpack配置文件中添加插件:
const webpack = require('webpack'); module.exports = { // ...其他打包配置 plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] };
之后你在TypeScript中正常导入AngularJS即可,Webpack会自动在全局注入jQuery,AngularJS初始化时就能检测到它:
import * as angular from 'angular'; export default ['$window', function($window) { let position = angular.element($window).scrollTop(); }];
额外提示
确保你已经安装了对应的类型声明包:
npm install @types/jquery @types/angular --save-dev
这样TypeScript就能正确推断angular.element()返回的是jQuery对象,不会再抛出scrollTop不存在的类型错误。
内容的提问来源于stack exchange,提问作者Lucas van Heerikhuizen

