项目总结 - ts中的declare let type: any和对.d.ts文件类型的认识

项目中用的是angular5.0+ionic3.0,由于现在angular现在都是用typescript写的了,虽然说typescript是Javascript的超集,但是在项目中还是会有一些问题,那就是全js写的插件怎么能引入到typescript写的模块呢?
TypeScript 的核心在于静态类型,我们在编写 TS 的时候会定义很多的类型,但是主流的库都是 JavaScript 编写的,并不支持类型系统。那么如何让这些第三方库也可以进行类型推导呢?
这篇文章我们来讲解 JavaScript 和 TypeScript 的静态类型交叉口 —— 类型定义文件。
之前在做项目的时候,老是看到这种写法,请看下面的代码:

    import { ViewChild, ElementRef } from "@angular/core";
    import { Company } from "../company/company";
    import { Electronic } from "../sign/electronic/electronic";
    import { Auth } from "../auth-pop/auth";
    import { Credit } from '../credit-pop/credit';
    
    declare let Talking: any;
    declare let Push: any;
    declare let cordova: any;
    declare let Swiper: any;

从上面的代码我们可以看到有import的导入,还有declare的声明,为什么会这样写?下面会一一讲解

import { Electronic } from "../sign/electronic/electronic";

这行代码表示从electronic.ts引入我们定义的Electronic类,我们先看一下electronic.ts

import { Component } from "@angular/core";
import { NavController, NavParams, ModalController,Tabs, Events } from "ionic-angular";
import { CallNumber } from '@ionic-native/call-number';
import { Storage } from "@ionic/storage";

@Component({
  templateUrl: "electronic.html",
  providers: [CallNumber]
})
export class electronic {
  constructor(
  ) {      
  }
  ngOnInit() {
  }
  ionViewDidEnter() {
  }
}

这个导入想必大家都知道,那这个这个呢?

import { ViewChild, ElementRef } from "@angular/core";

ViewChild和ElementRef都是封装好的插件,它们也都是用js写的,为什么它们可以用import的方式导入进来呢,仔细去查看了一下,发现它们都有一个.d.ts结尾的文件
ViewChild ===》di.d.ts
ElementRef ===》element_ref.d.ts
可以看到它们都有一个对应的.d.ts的文件
那么这个.d.ts的文件到底是什么样的?有什么作用呢?
在 TypeScript 中,我们可以很简单的,在代码编写中定义类型:

interface IBaseModel {
    say(keys: string[] | null): object
}

class User implements IBaseModel {
    name: string
    constructor (name: string) {
        this.name = name
    }
}

但是主流的库都是 JavaScript 编写的,TypeScript 身为 JavaScript 的超集,自然需要考虑到如何让 JS 库也能定义静态类型。
TypeScript 经过了一系列的摸索,先后提出了 tsd(已废弃)、typings(已废弃),最终在 TypeScript 2.0 的时候重新整理了类型定义,提出了 DefinitelyTyped。
DefinitelyTyped 就是让你把 “类型定义文件(*.d.ts)”,发布到 npm 中,配合编辑器(或插件),就能够检测到 JS 库中的静态类型。

类型定义文件的以 .d.ts 结尾,里面主要用来定义类型。
我们来看一下element_ref.d.ts

/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/**
 * A wrapper around a native element inside of a View.
 *
 * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
 * element.
 *
 * @security Permitting direct access to the DOM can make your application more vulnerable to
 * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
 * [Security Guide](http://g.co/ng/security).
 *
 * @stable
 */
export declare class ElementRef {
    /**
     * The underlying native element or `null` if direct access to native elements is not supported
     * (e.g. when the application runs in a web worker).
     *
     * <div class="callout is-critical">
     *   <header>Use with caution</header>
     *   <p>
     *    Use this API as the last resort when direct access to DOM is needed. Use templating and
     *    data-binding provided by Angular instead. Alternatively you take a look at {@link Renderer}
     *    which provides API that can safely be used even when direct access to native elements is not
     *    supported.
     *   </p>
     *   <p>
     *    Relying on direct DOM access creates tight coupling between your application and rendering
     *    layers which will make it impossible to separate the two and deploy your application into a
     *    web worker.
     *   </p>
     * </div>
     * @stable
     */
    nativeElement: any;
    constructor(nativeElement: any);
}

从上面的代码我们可以提炼出最重要的一行代码

export declare class ElementRef {

从这行代码中我们也看到了declare
declare
declare 可以创建 *.d.ts 文件中的变量,declare 只能作用域最外层

declare var foo: number;
declare function greet(greeting: string): void;

declare namespace tasaid {
    // 这里不能 declare
    interface blog {
        website: 'http://tasaid.com'
    } 
}

基本上顶层的定义都需要使用 declare, class 也是:

declare class User {
    name: string
}
发布了130 篇原创文章 · 获赞 103 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/xiaolinlife/article/details/97670969