(一)、什么是声明文件
声明文件就是给js代码补充类型标注. 这样在ts编译环境下就不会提示js文件"缺少类型".
声明变量使用关键字declare来表示声明其后面的全局变量的类型, 比如:
// packages/global.d.ts
declare var __DEV__: boolean
declare var __TEST__: boolean
declare var __BROWSER__: boolean
declare var __RUNTIME_COMPILE__: boolean
declare var __COMMIT__: string
declare var __VERSION__: string
复制代码
看过vue3源码的同学一定知道这些是vue中的变量, 上面代码表示__DEV__等变量是全局, 并且标注了他们的类型. 这样无论在项目中的哪个ts文件中使用__DEV__, 变量ts编译器都会知道他是boolean类型.
即便你只写js代码, 也可以安装声明文件, 因为如果你用的是vscode, 那么他会自动分析js代码, 如果存在对应的声明文件, vscode会把声明文件的内容作为代码提示.
1、ts 中使用jQuery
jQuery('.a') // 直接写会报错 cannot find name ‘jQuery’
2、此时我们要给jQuery写声明
全局声明
直接在本文档中或放到jQuery.d.ts中
当然实际的声明文件远不止这么简单,但都是类、函数、变量声明的组合
声明变量使用关键字declare来表示声明其后面的全局变量的类型, 比如:
declare var jQuery: (selector: string) => any
declare var n: number;
// 使用
n=1
这个namespace代表后面的全局变量是一个对象:
// global.d.ts
declare namespace MyPlugin {
var n:number;
var s:string;
var f:(s:string)=>number;
}
// 使用
MyPlugin.s.substr(0,1);
MyPlugin.n.toFixed();
MyPlugin.f('文字').toFixed();
3、如果还不识别 添加tsconfig文件
// 告诉ts编译器编译目录下所有文件,找到jquery的声明
{
"include": ["**/*"]
}
4、DefinitelyTyped 是一个为第三方库写ts声明文件的一个社区
打包后放到 npm @type/XXX
5、react的声明文件react.d.ts
里面是遍历了react源文件(js文件无声明)然后给写的声明文件,声明文件中有源文件所有的函数,类等一一对应,我们写ts的时候用引入的是声明文件中的声明,编译的时候会找到声明对应源文件中的东西
export = React;
export as namespace React;
declare namespace React {
//
// React Elements
// ----------------------------------------------------------------------
type ElementType<P = any> =
{
[K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never
}[keyof JSX.IntrinsicElements] |
ComponentType<P>;
/**
* @deprecated Please use `ElementType`
*/
function createElement(
type: "input",
props?: InputHTMLAttributes<HTMLInputElement> & ClassAttributes<HTMLInputElement> | null,
...children: ReactNode[]): DetailedReactHTMLElement<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
function createElement<P extends HTMLAttributes<T>, T extends HTMLElement>(
type: keyof ReactHTML,
props?: ClassAttributes<T> & P | null,
...children: ReactNode[]): DetailedReactHTMLElement<P, T>;
// Context via RenderProps
interface ProviderProps<T> {
value: T;
children?: ReactNode;
}
react源码中
function createElement(type, config, children) {
var propName; // Reserved names are extracted
var props = {};
var key = null;
var ref = null;
var self = null;
var source = null;
........
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
}
(6)、让vue3支持this.$axios 模块声明
// main.ts
app.config.globalProperties.$axios = axios;
复制代码
功能上我们实现了"this.axios",但是ts并不能自动推断出我们添加了axios", 但是ts并不能自动推断出我们添加了axios",但是ts并不能自动推断出我们添加了axios字段, 所以添加如下声明文件:
// global.d.ts
// axios的实例类型
import { AxiosInstance } from 'axios'
// 声明要扩充@vue/runtime-core包的声明.
// 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.
declare module '@vue/runtime-core' {
// 给`this.$http`提供类型
interface ComponentCustomProperties {
$axios: AxiosInstance;
}
}
这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.