持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
遇到的问题及解决方法
最近使用 TypeScript 写案例时,在开发过程中遇到IDE 提示「无法重新声明块范围变量」,从而导致编译出错,报错图示如下:
原因: 因为在文件目录中写了两个ts文件,但是都定义了url变量。在 Commonjs 规范里,没有像 ESModule 能形成闭包的「模块」概念,所有的模块在引用时都默认被抛至全局,因此当再次声明某个模块时,TypeScript 会认为重复声明了两次相同的变量进而报错。
最简单的解决方法:是在报错的文件底部添加一行代码:export {}。这行代码会使TypeScript 认为当前文件是一个 ESModule 模块,因此不存在变量重复声明的可能性。
根据上面的解决方法,无法执行编译后的 JavaScript 代码,出现以下报错:
因为浏览器无法识别export 关键字
另一种解决方法:使用在TypeScript中使用命名空间,编译后,生成为JavaScript 代码中的匿名回调函数(立即执行函数)
namespace foo {
const url: string = 'https://randomuser.me/api?results=50';
}
var foo;
(function (foo) {
var url = 'https://randomuser.me/api?results=50';
})(foo || (foo = {}));
命名空间
命名空间一个最明确的目的就是解决重名问题。相当于是模块中的模块
JavaScript 为防止全局作用域变量重复声明引起命名冲突和变量污染,一般使用立即执行函数避免变量命名冲突。
TypeScript 中使用 namespace 来定义命名空间,可以在命名空间内部定义变量、函数表达式、函数声明、接口和 类等值。
语法:namespace 空间名字 {}
空间名字.内部定义的值 在命名空间外部调取命名空间的变量、方法、接口、类等
在外部调用命名空间中的值,则需要在值(函数、类和接口)的前面添加 export 关键字
import 关键字定义命名空间的别名
namespace SpaceName {
export interface InterfaceName { }
export class ClassName {
constructor(x: number, y: number) {
let sum = x + y;
console.log(sum); //3
}
}
}
// 定义别名: 引用命名空间导出的类 ClassName,通过别名访问
import add = SpaceName.ClassName;
new add(1,2);
命名空间支持嵌套,即可以将命名空间定义在另外一个命名空间中