美文网首页
TypeScript 详解之 TypeScript 模块

TypeScript 详解之 TypeScript 模块

作者: you的日常 | 来源:发表于2023-08-13 10:50 被阅读0次

    简介

    任何包含 import 或 export 语句的文件,就是一个模块(module)。相应地,如果文件不包含 export 语句,就是一个全局的脚本文件。

    模块本身就是一个作用域,不属于全局作用域。模块内部的变量、函数、类只在内部可见,对于模块外部是不可见的。暴露给外部的接口,必须用 export 命令声明;如果其他文件要使用模块的接口,必须用 import 命令来输入。

    如果一个文件不包含 export 语句,但是希望把它当作一个模块(即内部变量对外不可见),可以在脚本头部添加一行语句。

    export {};
    
    

    上面这行语句不产生任何实际作用,但会让当前文件被当作模块处理,所有它的代码都变成了内部代码。

    ES 模块的详细介绍,请参考 ES6 教程,这里就不重复了。这里主要介绍 TypeScript 的模块处理。

    TypeScript 模块除了支持所有 ES 模块的语法,特别之处在于允许输出和输入类型。

    export type Bool = true | false;
    
    

    上面示例中,当前脚本输出一个类型别名Bool。这行语句把类型定义和接口输出写在一行,也可以写成两行。

    type Bool = true | false;
    
    export { Bool };
    
    

    假定上面的模块文件为a.ts,另一个文件b.ts就可以使用 import 语句,输入这个类型。

    import { Bool } from './a';
    
    let foo:Bool = true;
    
    

    上面示例中,import 语句加载的是一个类型。注意,加载文件写成./a,没有写脚本文件的后缀名。TypeScript 允许加载模块时,省略模块文件的后缀名,它会自动定位,将./a定位到./a.ts

    编译时,可以两个脚本同时编译。

    $ tsc a.ts b.ts
    
    

    上面命令会将a.tsb.ts分别编译成a.jsb.js

    也可以只编译b.ts,因为它是入口脚本,tsc 会自动编译它依赖的所有脚本。

    $ tsc b.ts
    
    

    上面命令发现b.ts依赖a.js,就会自动寻找a.ts,也将其同时编译,因此编译产物还是a.jsb.js两个文件。

    如果想将a.tsb.ts编译成一个文件,可以使用--outFile参数。

    $ tsc --outFile result.js b.ts
    
    

    上面示例将a.tsb.ts合并编译为result.js

    import type 语句

    import 在一条语句中,可以同时输入类型和正常接口。

    // a.ts
    export interface A {
      foo: string;
    }
    
    export let a = 123;
    
    // b.ts
    import { A, a } from './a';
    
    

    上面示例中,文件a.ts的 export 语句输出了一个类型A和一个正常接口a,另一个文件b.ts则在同一条语句中输入了类型和正常接口。

    这样很不利于区分类型和正常接口,容易造成混淆。为了解决这个问题,TypeScript 引入了两个解决方法。

    第一个方法是在 import 语句输入的类型前面加上type关键字。

    import { type A, a } from './a';
    
    

    上面示例中,import 语句输入的类型A前面有type关键字,表示这是一个类型。

    第二个方法是使用 import type 语句,这个语句只能输入类型,不能输入正常接口。

    // 正确
    import type { A } from './a';
    
    // 报错
    import type { a } from './a';
    
    

    上面示例中,import type 输入类型A是正确的,但是输入正常接口a就会报错。

    import type 语句也可以输入默认类型。

    import type DefaultType from 'moduleA';
    
    

    import type 在一个名称空间下,输入所有类型的写法如下。

    import type * as TypeNS from 'moduleA';
    
    

    同样的,export 语句也有两种方法,表示输出的是类型。

    type A = 'a';
    type B = 'b';
    
    // 方法一
    export {type A, type B};
    
    // 方法二
    export type {A, B};
    
    

    上面示例中,方法一是使用type关键字作为前缀,表示输出的是类型;方法二是使用 export type 语句,表示整行输出的都是类型。

    下面是 export type 将一个类作为类型输出的例子。

    class Point {
      x: number;
      y: number;
    }
    
    export type { Point };
    
    

    上面示例中,由于使用了 export type 语句,输出的并不是 Point 这个类,而是 Point 代表的实例类型。输入时,只能作为类型输入。

    import type { Point } from './module';
    
    const p:Point = { x: 0, y: 0 };
    
    

    上面示例中,Point只能作为类型输入,不能当作正常接口使用。

    importsNotUsedAsValues

    输入类型的 import 语句,编译时怎么处理呢?

    TypeScript 提供了importsNotUsedAsValues编译设置项,有三个可能的值。

    (1)remove:这是默认值,自动删除输入类型的 import 语句。

    (2)preserve:保留输入类型的 import 语句。

    (3)error:保留输入类型的 import 语句(与preserve相同),但是必须写成 import type 的形式,否则报错。

    请看示例,下面是一个输入类型的 import 语句。

    相关文章

      网友评论

          本文标题:TypeScript 详解之 TypeScript 模块

          本文链接:https://www.haomeiwen.com/subject/oosnpdtx.html