
在 node.js 项目中为 `array` 接口添加自定义属性(如 `isempty`、`first` 等)时,仅声明类型是不够的——必须显式导入实现文件,否则运行时报错“property does not exist on type”,因为 typescript 类型声明不自动触发 javascript 运行时行为。
TypeScript 的类型扩展(如 declare global { interface Array
因此,正确的做法是:
-
将类型声明与运行时实现分离(推荐):
- 创建 array.extensions.d.ts(仅含 declare global),用于类型提示;
- 创建 array.extensions.ts(不含 declare,纯实现逻辑),用于实际挂载属性和方法。
确保 .ts 实现文件被至少一次导入:
TypeScript 不会自动执行未被引用的模块。即使你在 tsconfig.json 中配置了 "typeRoots",也仅影响类型查找路径,不影响代码执行。必须通过 import(哪怕无命名导入)显式加载该文件,触发其顶层代码执行。
✅ 正确示例(src/shared/extensions/array.extensions.ts):
Magic CMS网站管理系统(政企版)采用PHP+Mysql架构,再原CMS系统的基础上精简出适合企业政府客户使用版本,继承了原系统的快捷,高效,灵活,实用的特点,保留了核心功能,系统支持自定义模版(极易整合dede模板)、支持扩展插件,自定义模型等功能,保留了文章模型,视频模型,图集模型,产品模型,能够胜任企业多种建站需求。BUG修复:1.修改了程序安装时部分数据无法正常导入的错误2.修改了程
// src/shared/extensions/array.extensions.ts
Object.defineProperty(Array.prototype, 'isEmpty', {
configurable: true,
get() {
return this.length === 0;
},
});
Object.defineProperty(Array.prototype, 'isNotEmpty', {
configurable: true,
get() {
return this.length > 0;
},
});
Object.defineProperty(Array.prototype, 'first', {
configurable: true,
get() {
return this[0];
},
});
Object.defineProperty(Array.prototype, 'last', {
configurable: true,
get() {
return this[this.length - 1];
},
});
Array.prototype.remove = function (o: T): T[] {
const i = this.indexOf(o);
if (i > -1) {
return this.splice(i, 1) as T[];
}
return [];
}; ✅ 在入口文件(如 src/index.ts)中显式导入:
// src/index.ts
import './shared/extensions/array.extensions'; // ← 关键:触发运行时挂载
console.log(['a', 'b'].isEmpty); // true
console.log([1, 2, 3].first); // 1
console.log(['x'].remove('x')); // []⚠️ 注意事项:
- ❌ 不要给 .d.ts 文件写运行时代码(如 Object.defineProperty),TS 编译器会忽略它;
- ✅ .d.ts 文件应仅用于类型声明,并放在 typeRoots 或 node_modules/@types/... 下供全局识别;
- ✅ 若使用 typeRoots,确保目录结构匹配(如 typeRoots: ["./src/shared/extensions"] 要求 ./src/shared/extensions/array.extensions.d.ts 存在且导出为空);
- ? 所有扩展必须在使用前完成挂载(通常在应用启动早期 import);
- ? 避免重复导入同一扩展文件(可能导致多次定义警告,虽一般无害,但建议用 export {} 确保其为模块)。
总结:TypeScript 类型是“说”,JavaScript 实现是“做”。扩展原生原型,既要“说清楚”(.d.ts),更要“做出来”(.ts + 显式 import)。缺一不可。









