在 TypeScript(isolatedModules: true)中,就像在 ECMAScript 2015 中一样,任何包含顶级import或output的文件都被视为模块。
相反,没有任何顶级import或output声明的文件被视为其内容在全局范围内可用的脚本(因此可直接在模块中使用)。
1.申明全局类型/变量/函数
1.1: 在包含import/export的.ts/.d.ts文件中,使用global从模块内部将声明添加到全局范围
import type { App } from "vue";
declare global {
// 全局类型
interface myInterFace {
app: App
}
// 全局变量
const $: any
// 全局函数
const createApp: typeof import('vue')['createApp']
// 对已有申明进行扩充 ??
interface Array<T> {
toObservable: () => {};
}
// 不能申明模块
// module xxxx
}
- 申明的全局函数createApp可使在main.ts不必import { createApp } from 'vue'即可直接const app = createApp(App),这也是插件unplugin-vue-components中使用的方法
1.2: 在不包含import/export的.d.ts文件中,直接申明
// 全局类型
declare interface myInterFace {
}
// 全局变量
declare const $: any
// 全局函数
declare const myFun: (str: string) => string
// 对已有申明进行扩充 ?? 不用declare ??
interface Array<T> {
toObservable: () => {};
}
// 申明模块 // import{ a }form 'loadsh' loadsh.a
declare module '*loadsh' {
let a: stirng
}
- 注意:如果在.ts文件中这样定义时,因为开启了(isolatedModules: true),所以会导致报错(需要顶级的import/output),倘如加入export {} 会使这些申明变成了模块内的局部申明,并非全局申明。
2. 对某一模块内的已有申明的扩充
2.1 在.ts/.d.ts文件中通过导入的方式(就已是一個模块)对已有类型进行扩充声明
// observable.ts
export interface Observable{
}
// map.ts
declare module "./observable" { // 对该模块(文件)内的已有申明进行扩充
interface Observable {
map: () => {};
}
}
// consumer.ts
import { Observable } from "./observable";
// import "./map"; //?
let o: Observable;
o.map();
// dependencies vue
export interface ComponentCustomProperties{
}
// xx.ts
import axios from 'axios'
declare module 'vue' { // 对该模块(文件)内的已有申明进行扩充
// 用于增强组件实例类型以支持自定义全局属性。
interface ComponentCustomProperties {
$http: typeof axios
}
}
// App.vue
getCurrentInstance()?.proxy?.$http()
3. Vue的解释
类型扩展的位置:
我们可以将这些类型扩展放在一个 .ts 文件,或是一个影响整个项目的 *.d.ts 文件中。无论哪一种,都应确保在 tsconfig.json 中包括了此文件。
对于库或插件作者,这个文件应该在 package.json 的 types 属性中被列出。
为了利用模块扩展的优势,你需要确保将扩展的模块放在 TypeScript模块中。
也就是说,该文件需要包含至少一个顶级的 import 或 export,即使它只是 export {}。
如果扩展被放在模块之外,它将覆盖原始类型,而不是扩展!
模块名称的解析方式与导入/导出中的模块说明符相同。然后,扩充中的声明将合并,就像它们在与原始声明相同的文件中一样。
但是,需要记住两个限制:
- 您不能在扩充中声明新的顶级声明,只能对现有声明进行修补。
- 默认导出也不能扩充,只能扩充命名导出(因为您需要通过导出的名称扩充导出,并且默认是保留字)