TypeScript学习笔记之三

131 阅读3分钟

Day18 类型声明Declaration

常见的类型检查指令

  • ts-igonre
// 常见的忽略ts检查的指令,可以忽略下行代码的类型检查。
// @ts-ignore
const name: number = '2'; // 没有报错
  • ts-expect-error
// 需要下行代码存在错误,否则的话就报错
// @ts-expect-error
const str: number = 2; // 抛错 Unused '@ts-expect-error' directive.ts(2578)
  • ts-check、ts-nocheck
// 这两个指令作用于整个文件
// ts-nocheck 表示此文件不再接受类型检查

// @ts-nocheck
const num:number = '2' // 没有报错
// 这两个指令还可以用于js文件中,通过类型推到和jsdoc对js文件进行不完全的类型检查。
// @ts-check
let age = 10; // age可以推导出类型为number

/** @type {string} */
let name = '200';
name = 200; // 不能将类型“number”分配给类型“string”。ts(2322)

类型声明declaration

ts文件在编译之后,生成的.d.ts文件中就包含了declaration声明。

const num:number = '2'

const handler = (input:number)=>{
    return input + 1
}

// 对应生成的.d.ts文件
declare const numnumber;
declare const handler(input: number) => number;

通过额外的类型声明文件,即.d.ts文件,在核心代码文件以外去提供对类型的进一步补全。 使用declare关键字编写的.d.ts文件,应用于以下三个常见场景。

// 老旧的npm包中,没有类型定义.
import foo from 'noTsNpmModule" // 指代没有类型声明的npm包

declare Module 'noTsNpmModule'{
    const foo : ()=>number;
    export default foo;
}
// 对于非代码文件,添加类型声明,如.md, .css, .png
import some from 'test.md'

declrate module '*.md'{
    const some:string;
    export default some;
}
// 对于项目中定义的一些全局变量,如window对象下的一些方法
// 由于lib.dom.d.ts中已经定义了window的类型
// 所以在给window新增类型的时候,可以用interface声明一个window类型,因为这些接口声明会被合并
interface Window{
    track:(customData:any)=>void
}
window.track({})

@types/ 命名的npm包

@types/ 开头的这一类 npm 包均属于 DefinitelyTyped ,它是 TypeScript 维护的,专用于为社区存在的无类型定义的 JavaScript 库添加类型支持,常见的如@types/node、@types/lodash。

三斜线指令

类似导入语句,声明当前文件所依赖的其他类型声明。

以下三种类型,引入依赖的方式不同,根据路径或包名,目的都是引入依赖的文件
// path属性,对应的值为相对路径,编译时会根据路径去查找。
/// <reference path="./other.d.ts" />
// type属性,对应的值为一个包名,node->@types/node包
/// <reference types="node" />
// lib属性,dom->lib.dom.d.ts文件
/// <reference lib="dom" />

命名空间namespace

// 命名空间中变量需要导出后,才能通过spaceA.A形式进行访问。
export namespace SpaceA {
  export class A {}
  // namespace 嵌套
  export namespace SpaceInside{
    export class Inside{}
  }
}

export namespace SpaceB {
  export class B {}
}

const a = new SpaceA.A();
// 命名空间类似于模块化方案,上面的ts编译后的代码
export var SpaceA;
(function (SpaceA) {
    class A {
    }
    SpaceA.A = A;
    let SpaceInside;
    (function (SpaceInside) {
        class Inside {
        }
        SpaceInside.Inside = Inside;
    })(SpaceInside = SpaceA.SpaceInside || (SpaceA.SpaceInside = {}));
})(SpaceA || (SpaceA = {}));

export var SpaceB;
(function (SpaceB) {
    class B {
    }
    SpaceB.B = B;
})(SpaceB || (SpaceB = {}));
const a = new SpaceA.A();
// namespace 支持合并操作
export namespace SpaceB {
  export namespace B {}
}

export namespace SpaceB{
    export namespace B{
        export function run(){}
    }
}

const b = SpaceB.B.run();

使用jsdoc

使用这种方法,获取到webpack中configuration的类型提示。

 /** @type {import ("webpack").Configuration} */
const config = {
  entry
}