TypeScript Writing .d.ts files(编写声明文件)
当使用扩展的JavaScript库或者插件API的时候,将需要使用声明文件(.d.ts)来描述库的类型。本文内容将包括如何编写声明文件相关的一些高级概念,然后用一些例子来展示如何将各式各样的概念与声明文件的描述相匹配。
流程
写.d.ts最好是从库的说明文档开始,而不是代码。从说明文档开始可以保证思维不受实现细节的影响,并且比阅读JS代码容易理解。下面的例子假设是根据说明文档写的,并且提供调用代码。
命名空间
当定义接口(例如"options"对象)的时候,你可以选择是否将这些类型放入一个模块中。这需要主观判断,如果.d.ts文件使用者更多的是用这些类型定义变量或者参数,并且类型的命名不会产生冲突,则将其放在全局命名空间较好。如果该类型不能够被直接引用,或者不能给一个唯一并且合理的命名,使用一个模块来防止与其他类型的冲突。
回调函数
很多JavaScript库都将函数作为参数,之后传入调用此函数时所用到的已知参数列表。在编写这些类型的函数签名时,不可以将这些参数标记为可选参数。正确的方式是想想"需要提供哪些参数?"(针对使用.d.ts的开发人员),而不是"哪些参数将被用到?"(针对函数被调用的时候)。
可扩展性和声明合并
当编写定义文件时,需要记住TypeScript的扩展现有对象的规则。可以选择使用匿名函数类型或者接口类型来声明一个变量:
声明一个匿名的类型:
declare var MyPoint: { x: number; y: number; };
声明一个接口类型:
interface SomePoint { x: number; y: number; }
declare var MyPoint: SomePoint;
从使用者角度来看,这些声明其实是一样的,但是SomePoint类型能够通过接口合并扩展:
interface SomePoint { z: number; }
MyPoint.z = 4; // OK
是否想让声明的变量可扩展是主观判断的。通常这也比较符合JavaScript库的目的。
类的分解
TypeScript中,类会创建两种单独的类型:实例类型,定义类的实例有哪些成员类型;构造函数类型,定义类的构造函数有哪些成员类型。构造函数的类型也被称为“静态部分”类型,因为它包含了类的静态成员。
虽然你可以使用关键字"typeof"来获取类的静态部分的类型,有时候使用类的分解模式来写定义文件是很有必要的,它可以明确的分离类的实例和静态类型。
标准模式:
class A {
static st: string;
inst: number;
constructor(m: any) {}
}
分解模式:
interface A_Static {
new(m: any): A_Instance;
st: string;
}
interface A_Instance {
inst: number;
}
declare var A: A_Static;
两种模式差异:
1.标准模式的类可以使用extends继承;分解模式不可以。这可能在TypeScript以后的版本中被改善,如果可以需要允许任意使用extends表达式。
2.都允许在后面添加静态部分的成员(通过合并声明)。
3.分解模式允许在后面添加实例部分的成员,而标准模式的不允许。
4.当使用分解模式的时候,需要为更多的类起一个合理的名称。
命名规则
一般来说,不需要给接口加上前缀I(如:IColor)。因为TypeScript中的接口比C#或Java里的接口具有更广泛的意义,加I的命名规则基本上没什么用。
案例
下面看例子吧。每个例子都已经提供了库的简单使用(这里需要自己对函数/对象进行脑补),然后就是定义精准类型的代码。如果有多个良好的声明方式,也会列出来。
选项对象(参数选项)
使用代码:
animalFactory.create("dog"); // 未通过验证: 如果给定options,必须提供name
animalFactory.create("giraffe", { name: "ronald" });
animalFactory.create("panda", { name: "bob", height: 400 });
animalFactory.create("cat", { height: 32 }); // 未通过验证: 如果给定options,必须提供name
类型声明:
module animalFactory {
interface AnimalOptions {
name: string;
height?: number;
weight?: number;
}
function create(name: string, animalOptions?: AnimalOptions): Animal;
}
带有属性的函数
使用代码:
zooKeeper.workSchedule = "morning";
zooKeeper(giraffeCage);
类型声明:
// 注意:函数必须处于模块之前
function zooKeeper(cage: AnimalCage);
module zooKeeper {
var workSchedule: string;
}
可使用关键字new也可直接调用的方法
使用代码:
var w = widget(32, 16);
var y = new widget("sprocket");
// w和y都是widgets
w.sprock();
y.sprock();
类型声明:
interface Widget {
sprock(): void;
} interface WidgetFactory {
new(name: string): Widget;
(width: number, height: number): Widget;
} declare var widget: WidgetFactory;
全局/封闭的库
使用代码:
// 可以这样写
import x = require('zoo');
x.open();
// 或者
zoo.open();
类型声明:
module zoo {
function open(): void;
} declare module "zoo" {
export = zoo;
}
外部模块中的单一复杂对象
// 可链式操作的eagles
import eagle = require('./eagle');
// 直接调用
eagle('bald').fly();
// 使用关键字"new"
var eddie = new eagle(1000);
// 设置属性
eagle.favorite = 'golden';
类型声明:
// 注意:在这里可以使用任何名称,但是整个文件中名称都要相同。
declare function eagle(name: string): eagle;
declare module eagle {
var favorite: string;
function fly(): void;
}
interface eagle {
new(awesomeness: number): eagle;
} export = eagle;
// 顺带加一点,node编译需要加--module,这个在TypeScript Modules(模块)中有提到,也给出了可运行的案例
回调函数
使用代码:
addLater(3, 4, (x) => console.log('x = ' + x));
类型声明:
// 注意:"void"返回类型在这里优先
function addLater(x: number, y: number, (sum: number) => void): void;
本篇基本脑补过来的... 后续如果工作中有使用到再记录详细的使用,之前一些列的TypeScript使用手册的随笔中,代码是经过修改成可运行的,还需要继续努力,不断改善自己,编写更高质量的代码。
TypeScript Writing .d.ts files(编写声明文件)的更多相关文章
- TypeScript学习笔记(八) - 声明文件
本篇将介绍TypeScript的声明文件,并简单演示一下如何编写和使用声明文件.本篇也是这个系列的最后一篇. 一.声明文件简介 TypeScript作为JavaScript的超集,在开发过程中不可避免 ...
- TypeScript完全解读(26课时)_20.声明文件
首先学习识别已有的js库的类型 识别已有的js库的类型 UMD既可以作为全局库使用,也可以作为模块使用 先在着手来编写一个全局的库 新建文件 接收一个title,改变页面title的值 这里用到 &a ...
- 如何编写 Typescript 声明文件
使用TypeScript已经有了一段时间,这的确是一个好东西,虽说在使用的过程中也发现了一些bug,不过都是些小问题,所以整体体验还是很不错的. TypeScript之所以叫Type,和它的强类型是分 ...
- TypeScript声明文件
为什么需要声明? 声明的本质是告知编译器一个标识符的类型信息.同时,在使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全.接口提示等功能. 声明在TypeScript中至关重要,只有通过 ...
- TypeScript 如何编写类库声明文件 .d.ts
TypeScript 如何编写类库声明文件 .d.ts how to write a d.ts file declaration-files/ https://www.typescriptlang.o ...
- TypeScript 的声明文件的使用与编写
https://fenying.net/2016/09/19/typings-for-typescript/ TypeScript 是 JavaScript 的超集,相比 JavaScript,其最关 ...
- JS如何捆绑TypeScript声明文件
前话 TypeScript是JavaScript类型的超集 这是TypeScript的文档介绍的一句话,那么他们存在联系呢? 我的理解是,TypeScript在JavaScript基础上引入强类型语言 ...
- TS学习随笔(七)->声明文件
now我们来看一看TS怎么声明文件, 在JS里面我们经常会使用各种第三方类库,引入方式也不太相同,常见的就是在HTML中通过script标签引入,然后就可以使用全局变量$或者jQuery了 我们通常这 ...
- TypeScript 之 声明文件的发布
https://www.tslang.cn/docs/handbook/declaration-files/publishing.html 发布声明文件到npm,有两种方式: 与你的npm包捆绑在一起 ...
随机推荐
- sp_executesql得到执行sql语句的返回值
执行 sql语句,得到 变量的值 ' declare @Partition int; ); ); SET @SQLString = N'SELECT @RangeKeyOUT = $PARTITION ...
- 全新的membership框架Asp.net Identity(1)——.Net membership的历史
在Asp.net上,微软的membershop框架经历了Asp.net membership到Asp.net simple membership,再到现在的Asp.net Identity. 每一次改 ...
- StringUtils工具类
StringUtils源码,使用的是commons-lang3-3.1包.下载地址 http://commons.apache.org/lang/download_lang.cgi 以下是String ...
- SSDB安装配置记录
SSDB的性能很突出,与Redis基本相当了,Redis是内存型,容量问题是弱项,并且内存成本太高,SSDB针对这个弱点,使用硬盘存储,使用Google高性能的存储引擎LevelDB,适合大数据量处理 ...
- 【转】Java并发编程:Lock
阅读目录 一.synchronized的缺陷 二.java.util.concurrent.locks包下常用的类 三.锁的相关概念介绍 来自: http://www.importnew.com/18 ...
- shell数值运算与运算符
- 无需FQ,自建本地CDN,秒上StackOverFlow!
StackOverflow是一个面向程序员的技术问答平台.可是在不FQ的情况下,浏览StackOverflow是一件让人极不舒服的事情,常常需要等待数十秒页面才慢慢显示出来.本文我教大家一种能够流畅地 ...
- [WPF系列]-DataBinding(数据绑定) 自定义Binding
自定义Binding A base class for custom WPF binding markup extensions BindingDecoratorBase Code: public c ...
- C# 将绝对路径转换为相对路径
引言 在项目中常需要将绝对路径,转换为相对路径,来增加程序相关配置的的灵活性(不用因为整体挪个位置就导致我们的程序不能正常工作) 解决问题方法 自己写代码解决: private strin ...
- EF with (LocalDb)V11.0
EF虽说对LocalDb支持的不错,但LocalDb有自身的缺陷(不想sqlite那样数据库文件可以像普通文件一样使用). LocalDb在一个计算机上会对数据库有唯一性约束,要求本机的localdb ...