TypeScript 的三类声明: 命名空间, 类型与值

经常会有同学问到如下一些问题:

  • 如何为函数对象添加方法?
  • 如何按需导入模块?
  • 类实现 (implements) 类怎么理解?
  • 为什么用 `const` 为某个命名空间建立引用后, 无法再使用它之下的类型?

相关的问题还有很多, 不再一一举例. 而这些问题, 都与标题中提到的 TypeScript 的三类声明有关. 于是奉上可能是目前为止我发送次数最多的关于 TypeScript 的链接:
Declaration Merging

(好吧发现改版了, 链接也不是原来发的链接了).

三类声明

在 TypeScript, 声明的实体有三种类: 命名空间
, 类型

(这里用斜体表示声明的实体类别, 下同):



  • 命名空间

    这里的 命名空间
    是指声明的分类, 不是具体的实体, 请注意区别. 一个 命名空间
    内可以包含
    类型
    . 对 命名空间
    建立应用需要使用 `import` 语句, 如果使用 `const`, `let` 或 `var` 会使新的实体不再具有 命名空间

    的属性.


  • 类型

    类型
    可以描述一个
    的 “形状”. 通俗一些讲, 类型
    可以是写在变量声明时冒号右边的部分, 也可以是类型别名的 “值” (如 `type Foo = string;`). 类型
    只能存在于 命名空间
    中.



  • 在编译为 JavaScript 后,
    是这三者中唯一会被保留的一种, 而 命名空间
    类型
    都会被清除. 这点比较重要.

同一个实体属于至少其中一类, 至多三类. 以下是各种声明与所属类别之间的对应关系:

  • 命名空间 (namespace, module)
    : 命名空间
    ,
    .
    这里的命名空间是指声明的实体, 请注意区别. 在当前的 TypeScript 版本中, 如果一个命名空间不包含具有
    的声明, 那么它也不具有
    , 而仅仅属于 命名空间
    一类.
  • 类 (class)
    : 类型
    ,
    .
  • 枚举 (enum)
    : 类型
    ,
    .
  • 接口 (interface)
    : 类型
    .
  • 类别名 (type)
    : 类型
    .
  • 函数 (function)
    :
    .
  • 变量 (let, const, var, parameters)
    :
    .

现在关于类实现类的问题就很好理解了, `implements` 只关心后者是否具有 类型
属性, 而并不关心多出的
属性. 与之对应的, `extends` (较新版本) 则是只关心后者是否具有特定的
属性, 而不关心是否具有 类型
属性.

声明合并

三类声明的实体可以在一定条件下进行合并, 这里以为函数或类添加方法和接口为例:

// 函数与接口合并

function Foo(): Foo {
    return { bar: 'abc' };
}

interface Foo {
    bar: string;
}

// 函数与命名空间合并

function foo() {
    console.log('Hello, TypeScript!');
}

namespace foo {
    export function bar() { }
}

// 类与命名空间合并

class Foo {
    bar: Foo.Bar;
}

namespace Foo {
    export interface Bar { }
}

除了不同分类的声明可以合并外, 在一定限制内, 相同的声明类型也可以合并. 如:

// 接口合并

interface Foo {
    abc: string;
}

interface Foo {
    def: number;
}

// 类与接口合并

class Bar { }

interface Bar {
    abc(): void;
}

// 命名空间合并

namespace Biu {
    export function pia() { }
}

namespace Biu {
    export function xiu() { }
}

更多例子可以参见文章开头给出的链接.

理解 TypeScript 如何处理这些声明在需要和原生 JavaScript 代码打交道时尤为有用, 也能帮助使用者更好的解释一些使用过程中的困惑. 下一篇文章会为大家介绍 TypeScript 中类型系统 (表面上) 运作的方式及类型收窄的应用, 欢迎关注~

稿源:JavaScript in TypeScript (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » TypeScript 的三类声明: 命名空间, 类型与值

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录