通常我们在定义 ts 类型声明时,在 .d.ts 文件中使用 declare 关键字就能正常使用。这基本可以满足全局常量或者一些简单的类型定义。但是不排除更为复杂的使用条件,比如在某个模块中使用其他模块声明的类型,如果在 .d.ts 文件中使用了 import 或者 require 等方式引入了其他模块,那么 ts 就会将其视为一个模块,从而导致文件下的所有类型声明直接失效。
首先定义 global.ts,代码如下:
export interface GlobalState {
loading: boolean;
pageNum: number;
pageSize: number;
此时在 typings.d.ts 中想要使用 GlobalState 这个类型,就需要引入 global.ts 这个文件,如果直接在 typings.d.ts 文件顶部引入,就会导致其中的全局声明全部失效。
import { GlobalState } from 'global.ts';
declare interface Window {
_store: {
_state: any;
_dispatch: any;
在使用 window._store 的地方就会抛出错误,_store 在类型 Window 上不存在 。
TypeScript 与 ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块。相反地,如果一个文件不带有顶级的 import 或者 export 声明,那么它的内容被视为全局可见的(因此对模块也是可见的),这就是为什么有时候没有引用某个 .d.ts 文件,但是在该 .d.ts 文件内部的类型定义在其它文件中仍然能检测得到,这是因为该 .d.ts 文件定义的类型已经变成全局的了
通过创建全局命名空间的方式,将想要使用的类型声明挂载到全局命名空间上。
import { GlobalState, GlobalDispatch } from 'global.ts';
declare namespace GlobalType {
interface G_State extends GlobalState {}
interface G_Dispatch extends GlobalDispatch {}
export = GlobalType;
export as namespace GlobalType;
然后在想要使用 GlobalState 类型声明的文件中,使用 GlobalType.GlobalState。
declare interface Window {
_store: {
_state: GlobalType.G_State ;
_dispatch: GlobalType.G_Dispatch ;
需要注意的是,如果全局命名空间发生了重复,重复的命名空间就会发生覆盖,且没有提示或报错,所以声明全局命名空间,一定注意不要重复。
TypeScript的 d.ts 声明文件中的 export = 语句的作用什么?
TypeScript 可以将 ts 代码生成 CommonJs 规范和 AMD 规范,由于两者并不兼容,所以就有了 export = 语法将两者进行统一,以至于让 ts 支持。
TypeScript的 d.ts 声明文件中的 export as namespace 语句的作用什么?
export as namespace 表示将某个命名空间挂载到全局命名空间上,从而可以通过全局变量的形式使用
挂载全局namespace
ts正确推导类型声明