ts的类型声明有两个特征:

  • 在ts开发中,为了使用一些只有js版本的库,可以通过使用类型声明,在ts文件中直接使用库。
  • 类型声明的代码在编译后会被删除,不会影响真正的代码

1. 类型声明

1. 基本类型声明

对于变量,函数,类,type,接口的声明

declare let name: string;
declare function getName(params: string):void;
declare class  Animal{name: string}
interface Person{
  name: string
}
type User = {
  name: string
}

2. 外部枚举声明

declare enum Season {
  SPRING,
  SUMMER,
  AUTUMN,
  WINTER
}
let seacons = [
  Season.SPRING,
  Season.SUMMER,
  Season.AUTUMN,
  Season.WINTER
]
// 常量枚举
declare const enum Season2 {
  SPRING,
  SUMMER,
  AUTUMN,
  WINTER
}

3. 命名空间声明-namespace

主要用于自定义声明含有很多属性的全局变量,如jquery库的$

// $作为对象时
declare namespace $ {
  function ajax(url: string, settings:any):void;
  let name: string;
  namespace fn {
    function extend(object: any):void
  }
}
// 示例
$.ajax('./url', {})
// $作为函数时
declare function $(selector: string): HTMLElement;
// 示例
$('#root')

2. 类型声明文件

类型声明的文件的后缀为 .d.ts。

对应的tsconfig.json中的相关配置参数有:

include: [
    "./src/**/*" // 表示ts编译时针对src文件夹下的所有的.ts后缀的文件,
    "./types/**/*"
]

如果不设置该属性,则默认编译所有文件夹下的文件。

1. 自定义第三方类型声明文件

在引入文件定义查找路径的规则时,需要在tsconfig.json中的compilerOptions中配置paths+baseUrl。

"baseUrl": "./",  /* 解决相对路径;设置paths时,该属性必须存在*/
"paths": {
    "*": ["types/*"]
},     /* import引入文件查找对应的声明文件时的相对于baseUrl的路径*/

src/index.ts

import * as jQuery from 'jquery';

jQuery.default.ajax('/users', {});

安装jquery

npm install -S jquery

自定义jquery的声明文件: types/jquery.d.ts

declare function jQuery(params:string): HTMLElement;
declare namespace jQuery {
  function ajax(url: string, setting: any): void;
}
export default jQuery;

2. 第三方类型声明文件库

类型声明文件的查找优先级

1. 根据配置文件的paths查找自定义的类型声明文件,如果无,向下
2. 查找node_modules/XXX/package.json中types字段,如果无,向下
3. 查找node_modules/XXX/index.d.ts
4. 查找node_modules/@types/XXX/index.d.ts

对于常用的js库的类型声明文件,有现成的声明文件@types/*。

示例:

1. 安装@types/jquery

2.直接使用

⚠️: 如果自定义的类型声明文件也存在时,会使用自定义的类型声明文件

import * as jQuery from 'jquery';

jQuery.ajax('./uers');

3. 类型声明扩展

本质上是扩展目标对象的属性值

1. 扩展全局变量-declare global

当前文件中使用了export关键字,为局部文件,需要在该文件中扩展全局变量

export{};
declare global {
  interface String {
    double(): string;
  }
  interface Window {
    myname: string;
  }
}

String.prototype.double = function(){
  return this.toLowerCase() + this;
}
console.log('lee'.double());


window.myname = "hello world"

2. 使用命名空间扩展

  • 使用命名空间扩展类

给类添加属性

class Form {
  username: Form.Item = ""; //Form在此处用作命名空间
  password: Form.Item = "";
}

// 使用declare时,内部不需要export;
// declare已经表明可以被外部使用
declare namespace Form {
  class Item{}
}
// 或者
/*
namespace Form {
  export class Item{}
}
*/
let form: Form = {
  username: "",
  password: ""
}
  • 使用命名空间扩展函数

给函数添加属性

declare function JQuery(selector: string): HTMLElement;
declare namespace JQuery {
  let name: string;
}
  • 使用命名空间扩展枚举

扩展枚举值的选项

enum Color {
  RED=1,
  BLUE
}
declare namespace Color {
  const GREEN = 3;
  const VIOLET = 4;
}
let color = Color.GREEN;
console.log(color)