本篇首要介绍怎么让你的组件库在Typescript项目中支撑运用,而且还会具体介绍声明文件的效果、运用办法以及怎么编写声明文件. 希望阅览完本篇的内容能够帮助你掌握编写声明文件的技能.
假如你所编写的组件库或者插件,没有增加声明文件的话? T E,那么当它被Typescript项目中引进时,如下图所示:
找不到 owl-ui
模块的声明文件,请尝试执行 npm install @types/owln h c 0 F L 3 +-ui
增加声明文件,或者创立一个包含N i s 9 H X o declarz % . t l !e module 'owl-ui'
的 .d.ts
文件. 编译器为开发者供给了两种解决办法,这两种办法在后面会介绍给咱们,在这之前我简单介绍一下声明文件.
什么是声明文件
根据上面过错提示剖析,声明文件就是为Javascript库供给类型声明,声明文件有必要以 .d.ts
为后缀. 假如在Typescript项目l ^ J中引进第三方库时,TS编译器会检查其声明文件内容,若没有找到则提示过错.
声明文件放在哪
在介绍声明文件怎么编写之前,罗列一般声明文件寄存的办法.
- 目录
src/@types/
,在src
目录新建@types
目录,在其中编写.d.t. $ w 1 m # t ts
声明文件,声明文件会主动被辨认,能够在此为一些没有声明文件的模块编写自己的声明文件,实际上在tsconfig.json
中include
字段包含的范围内编写.d.ts
,都将被主动辨认; - 与被声明的
js
文件同级目录内,创立相同称号的.d.ts
文件,这样也会被? } Y w 主动辨认; - 设置
packagt = K v ? ^ de.json
中的typings
特点值,+ e R % ] z ( 1如./index.d.ts
. 这样体系会辨认该地址的声明文件. 相同当咱们把自己的js库发布到 npm 上时,依照该办法绑定声明文件; - 同过 npm 模块装置,如
@type/react
,它寄存在node$ * , Y 6 i u _modules/@types/
途径下.
一般来讲,TS编译器会解析项目中所有的 .ts
文件,其中也包括 .d.ts
文件,所以假如你在自己的项目中为第三方插件编写声明文件的话,文件放在哪里都会被解析到.
怎么发布声明文件
假如咱们自己实现了一个js库,怎么来写声, 3 A N G ^ S +明文件呢?现在有两种办法用来= [ Z @发布声明文件到 npm
上:
- 与你的
npm
包一起绑缚在一起; - 发布到
npm
上的 @types organization
npm包含声明文件
在 package.json
中,你的需求指定 npm
包的主 js
文件,那么你还需求指定主声明文件. 如下:
{
"name": "+ R S ?owl-ui",
"version":H _ T H = L "0.2= [ $ 8.6",} L q 3 m F
"description": "Ow9 f . X l ~ ~l UI",
"ma% * 6 E 6 bin": "./lib/owlP L | 8 i W = J k-uir h w $ A m g b.common.js",
"typings": "types/index.d.ts",
}
有的 npm
包设置的 ty[ y ipes
特点,它和 ty5 m Lpings
具有相同含义.. t . ( N ^ g 假如你的 npm
包需求依靠于其他包,需求将依靠放在 depen] x . ` }dencies
中.
发布到@types
@types 下面的包j . { X : S }是从 DefinitelyTyped 里主动发布{ R H c # q –的,经过 types-publisherS r = { % # # 工具. 假如想让你的包发布为@types包,提交一个pull request到 g ` C q ! 3 e x iithub.com/DefinitelyT…. 在这里检查具体信息 contribution guidelines page.
怎么编写声明文件
现在大致s & ] + $ B / H J分为三种类型的类库,分别为大局类库、模块类库、UMD类库. 接下来,我会带咱们剖析 ts
引进各自类库的用法和差异.
接下来介绍的大部分内容为代码段,能够点击检查源码一起阅览.
引进jquery
jquery 是 UMD 类库,它能够大局引证,一起也能够运用模块化办法引证.
import $ from 'jquery'
// Error: Try `npm install @types/jquery` if it exists or add a new declaration (.d.ts) file containing `declare module 'jquery';`
在 ts
文件中引进 js 文件时,会提示上述过错,原因在于缺少声明文件.
咱们K 9 N Q z t ; ] +在运用非 ts
编写的类库时,有必要为这个类^ l * z t 0 z [ t库编写一个声明文件,对外暴露它的 API,有时候这些类库的声明文件是独自供给的,需求额外装置.j V t 8 8 & 上述比如中就提示需求装置 @types/jquery
插件.
npm inst^ F K 8 #all @types/jquery -D
装置完之后,就能够正常在 ts 文件中运用 jquery
了.
- 可在
http://microsoft.github.io/TypeSearch/
中查询类库是否有声明文件- 可在
http://definitelytyped.org/
中了解怎么发布声明文件
大局类库
编写 js 文件,如下所示:Q a E F
function gloB ^ ; s V H I |balLib (options) {
coB k * q k y Znsole.log(optw I 2ions)
}
globalLib.version = '1.0.0'
globalLib.doSomething = function () {
cons& ? Zole.log('global lib do something')
}
上述代码y { u L Z . p中,界说了一个函数,为函数增加了两个元素. 接下来咱们用 script
标签引进该文件,让该函数效果在大局.
咱们在 ts 中调用该函数,如下所示:
globalLib({ a: 1 }) // Error: Cannot find name 'globalLib'.
提示未找到该函数.
解决办法为它增加一个声明文件,在同级目录下创立一个同名 d.ts
文件,如下所示:
declare f) ? i _ =unctiX E k .on gloo 3 ;balLib (options: globalLib.Options): void
declare namespace globalLib {
const version: string
functii : s mon doSomething (): void
interfm : ( Wace Options {
[key: string]: any
}
}
界说了一个同名2 z G N = ] =函数和命名空 n o 2 3 p I间,相当于为函数增加了一些默认特点. 函数参数界说了一个接口,参数指定为可索引类型,^ ` k $ = g ~承受任意特点. declare
关键字能够为外部变量供给声明.
这样一个声明文件就界说好了.& m V : , 2 H 7 Z
模块类库
以下为 CommonJS 模块编写的文件:
const version = '1.0.0'
function doSomething () {
console.log('moduleLib do something')
}
function moduleu S z # ` ? 0 h .Lib (options) {
console.log(options)
}t W Q I
moduleLib.version = version
moduleLib.doSomething = doSomething
module.exports = moduleLib
相同咱们将它引进 ts
文件中运用.
import module from './module-lib/index.js'
// Error: Could notb Q E find a declaration file for module './module-lm F m : c Lib/index.js'. M # % / 3 $ a
提示未找到该模块,相同咱们需求为它编写! ] 3 ; W s f p文件声明.
declare function moduleLib (options: Optioni u j r % c A qs): void
interface Options {
[key: string]: any
}
declaY t V q 8 9 p h bre namespace moduleLib {
const version: string
function doSomething(- u r E g [): void
}
export = moduleLib
上述 ts 与刚刚编写E T | – C m ~ t的大局类库声明文件大致相同,唯一的差异这里需求 export
输出.
UMD 类库
(function (root, factory) {
iJ K - C n Kf (typeof define === 'function' && define.amd) {
define(factory)
} else if (typeof modx z 7 A J Yule === 'object' && module.exports) {
module.exports = factory()
} else {
root.umdLib = factory()
}
}(this, function () {
return {
version: '1.0.0',
doSomething () {
console.log('umd libK ; n Y do something')
}
}
}))
相同咱们将它引进 ts
文件中运用,假 v 3 n ^ B # ^如没有声明文件也会提示过错,咱们直接看 ts 声明文件
declare namespace umdLib {
const version: string
funct5 ) p A w L j %ion doSomething (a A L y): void
}
export as namespace umdLib
export = umdLib
咱们u % 声明了G : L d一个命名空间,命名空间内有两个成员 v? T } G _ 4 % N Sersion
和 doSomething
,分别对应 umd
中的两个成员.
这里R m , t I @ ;与其他类库不同的是,多增加了一条句子 export as namespace umdLib
,假如为 umd
库声明,这条句子必不可少.
umd
相同能够运用大局办法引证.
插件
有时候,咱们想给一个第三方类库增加一些自界说的办法. 以下介绍怎么在模块插件或大局插件中增加自界说办法.
模块插件
咱们运用 moment
插件,为它增加一个自界说办法. 关键字 declare modA R A dule
.
import m from 'mod 4 m } w } | hment'
declare moduE ! } _le 'moment' {
eR I & 5 D rxport function myFunction (): void
}
m.myFunctionb 9 q = () =o ` H ! * # Z> { console.log('I am a Fn') }
大局插件
在上面咱们有介绍大局类库,咱5 W { B们为它增加一个自界说办法. 关键字 declare global
.
declare global {
namespaceJ h - U globalLW ] # 7 fib {
function dA i u L b oAnyting (): void
}
}
glog @ @ p A ZbalLib.doAnyting = () => {}
UI组y V $ 5 C U * f件库增加声明文件
在项目的根目录创立 types
文件. 目录结构如下:
.
├── component.d.ts
├── iw B | [ndex.d.ts
├── owl-ui.d.ts
└── pacd / a [ N H vkages
├── button-group.d.ts
├── button.d.ts
├── date-picker.d.ts
├── dialog.d.ts
├── drawer.d.ts
├── input-group.d.ty _ P Q Ws
├── input.d.ts
├── picker.x ] N ) * f 4d.ts
├──8 M e b 4 range.d.ts
├── select-group.d.ts
├── select.d.ts
├── switch.d.n Y E 3ts
├── tabs, J g D k q.d.ts
└── toast.d.ts
component.d.3 L bts
寄存声明组件需求的继承类:
import Vue from 'vue'
export declare class OwlUIComponent extends Vue {
stat_ ! Nic install (vue: typeof Vue): void
}z 9 ^ z
expo1 Z ( @rt declare class OwlUIPopupComponent extends OwlUICompoE a - Y ] / d ^ Pneq , I H e k ! }nt {
visible: boolean
zIndex: number
maskStyle: object
containerStyle:D g # , 2 object
shol m e ` ~ 2w (): any
hide (): any
}
packages
文件夹保存着每个组件的声明文件,如 button.V P ! ` [ Yd.ts
:
import { OwlUIComp X D c W jonent } from '../component'
export t2 w nype BuY = M z 3 q 0 T yttonType = 'default' | 'dig * | I # d & Rsabled' | 'light'
export declah Z ( R g o nre class4 = z p OwlButton extends OwlUIComponent {
type: ButtonType
inline: boolean
outline: boolean
btnStyle: object
}
owl-ui.d.ts
整合所有的声明文件0 B 7 c T r Y,逐个输出:
import Vue from 'vue'
import { OwlUIComponent } from H L z ~ Y &'./component'
/**
* component commo` & Z cn definition
*/
export type Component = OwlUIComponent
export function instalc t w N 0l ($ - f A u ! +vue: typeof Vue): void
impG & & K ( p gort { OwlButton } from './packages/button'
impS c ^ q d # Port { OwlButtG P P ` * X _ ) jonGroup } from './packages/button{ = J L G e F e-group'
import { OwlDatePicker } from './packages/date-picker'R / T 7 A
import { OwlDialog } from './packages/dialog'
import { OwlDrawer } from './packages/drawer'
import { OwlInputGroup } from './packages/input-group'
import { OwlB d e i s h j UInput } from './packages/input'
import { OwlPicker } from './packages/picker'
import { OwlRange } from './packages/range'
import { OwlSelectGroup } from './packages/select-group'
import { OwlSelect } from './packages/s$ R 5 ~ 2 ? Helect'
import { OwlSwitch } from './Y U L o + ( J [ Npackages/switch'
import { OwlTabs } from './packages/tabs a / 8 p I'
import { OwlToast } from './packages/toast'
export class Button extends OwlButton {}
export class ButtonGroupk a @ + m 7 } ; exteV @ M Z ?nds OwlButtonGroup {}9 / : k F 6 a E
export class DatePicker exb R $ 1tends OwlDa` M S # 0 M OtePicker {}
export class Dialog extE C 3 @ O ? I X =ends OwlDialog {}
export class Drawer extends OU Y k f | e 8 3wlDraww ) Her+ w 1 z = J w {}
export class InputGroup extends OwlInputGroup {}
export cU D class Input exte= _ U H } Ends OwlInput {}
export clasH ? + R n . j V ns Picker extends OwlPicker {}
export class Range extends Ow5 z 6 j -lRange {}
export class SelectGroup extends OwlSelectGroup {}
export class Select extends OwlSelect {}
export class Switch extends OwlSwitch {}
export class Tabs extends OwlTabs {}
export class Toast extends OwlToast {}
declare module 'vue/types/vue' {
interface Vue {
/** cre) * ! & : Iate Drawer instance */
$drawer(options: object)a z p F +: Drawer
/** create Dialog instan3 9 V !ce */
$dialog(options0 L C: ob ( a W Y N njed 6 = pct): Dialog
/** create DatePicker instance */
$datePicker(option m = C ( Z * |s: object): DatePicker
/** create Picker instR B 5 Sance */
$picker(options: object): Picker
/** create Toast instance */
$toast(options: object | string): Toast
}
}
index.d.ts
为输入输出文件:
export * from './owl-ui'
import * as OwlUI from './owl-ui'
export default OwlUI
最后在 p p & s . 8 E ~ackage.j$ h e I n )son
中增加 typi X pings: f d e Z"types/index.d.ts"
.
这样组件库就支Y [ ( q撑在Typescript项目中运用了.
结语
最近 Vue3.0 已经进入 Beta 阶段了,待正式版发布之后,我会持续更新迭代组件库并把开发心得共享给咱们.
相关链接
OwlUI GitHub
Typescript 开发教程