乐趣区

关于javascript:面试官说说TypeScript扩展类型定义

小册

这是我整顿的学习材料,十分零碎和欠缺,欢送一起学习

  • 古代 JavaScript 高级小册
  • 深入浅出 Dart
  • 古代 TypeScript 高级小册
  • linwu 的算法笔记📒

扩大类型定义

在 TypeScript 中,咱们能够通过申明文件(.d.ts 文件)来为现有的 JavaScript 库提供类型定义,或者为现有的类型增加额定的属性和办法。这个过程通常被称为“类型申明扩大”。在这篇文章中,咱们将具体探讨如何通过申明文件扩大类型定义。

什么是申明文件?

在 TypeScript 中,申明文件是一种以 .d.ts 为扩展名的非凡文件,它不蕴含具体的实现,只蕴含类型申明。这些文件通常用来为已有的 JavaScript 库提供类型定义,使得咱们能够在 TypeScript 代码中更平安、更不便地应用这些库。

申明文件的次要内容是类型申明,包含变量、函数、类、接口等的类型定义。这些类型申明提供了一种形容 JavaScript 代码的构造和行为的形式,使得 TypeScript 编译器可能了解和查看 JavaScript 代码。

// types.d.ts
declare var foo: string;
declare function bar(baz: number): boolean;

在下面的申明文件中,咱们申明了一个全局变量 foo 和一个全局函数 bar,并别离给它们提供了类型申明。

declare

当咱们在 TypeScript 中编写申明文件时,咱们应用 declare 关键字来申明全局变量、函数、类、接口等类型。

declare 关键字用于通知 TypeScript 编译器某个标识符的类型,而不须要理论的实现代码。它用于在申明文件中形容 JavaScript 代码的类型。

上面是一些常见的用法:

1. 申明全局变量:

declare const myGlobal: string;

这个申明通知 TypeScript 编译器,存在一个名为 myGlobal 的全局变量,它的类型是 string

2. 申明全局函数:

declare function myFunction(arg: number): string;

这个申明通知 TypeScript 编译器,存在一个名为 myFunction 的全局函数,它承受一个 number 类型的参数,并返回一个 string 类型的值。

3. 申明全局类:

declare class MyClass {constructor(name: string);
  getName(): string;}

这个申明通知 TypeScript 编译器,存在一个名为 MyClass 的全局类,它有一个承受 string 类型参数的构造函数,并且有一个返回 string 类型的 getName 办法。

4. 申明命名空间

declare namespace MyNamespace {
  export const myVariable: number;
  export function myFunction(): void;}

这个申明通知 TypeScript 编译器,存在一个名为 MyNamespace 的全局模块 / 命名空间,它蕴含一个名为 myVariable 的变量和一个名为 myFunction 的函数。

通过应用 declare 关键字,咱们能够在申明文件中形容出咱们所须要的类型信息,以便 TypeScript 编译器进行类型检查和类型推断。

须要留神的是,declare 关键字只用于类型申明,不蕴含具体的实现代码。在应用申明文件时,咱们须要确保提供了理论的实现代码,以便程序在运行时能够拜访到所申明的类型。

5. 申明模块

当咱们在申明文件中应用 declare module 时,咱们能够定义一个模块,并在其中申明模块外部的类型。这样,其余文件在导入该模块时,就能够依照模块的名称来援用其中的类型。

declare module 'my-module' {
  export const myVariable: string;
  export function myFunction(): void;}

在这个示例中,咱们在 my-module 模块中申明了一个名为 myVariable 的变量和一个名为 myFunction 的函数,并通过 export 关键字将它们导出,使其在导入该模块时可见。

通过申明文件扩大类型定义

在某些状况下,咱们可能须要为已有的类型增加额定的属性或办法。比方,咱们可能在应用一个库时发现它短少一些咱们须要的类型定义,或者咱们可能想要为一些内置类型(如 stringArray)增加一些自定义的办法。

这时,咱们能够通过在申明文件中应用“申明合并”(Declaration Merging)来扩大类型定义。申明合并是 TypeScript 的一项个性,它容许咱们在多个地位申明同名的类型,而后 TypeScript 会将这些申明合并为一个类型。

例如,假如咱们想要为所有的数组增加一个 last 属性,该属性返回数组的最初一个元素。咱们能够在申明文件中为 Array 类型增加一个新的申明:

// types.d.ts
interface Array<T> {last: T;}

在下面的代码中,咱们通过申明一个同名的 Array 接口来为 Array 类型增加一个新的 last 属性。这样,咱们在 TypeScript 代码中应用数组时,就能够拜访这个新的 last 属性:

let nums: number[] = [1, 2, 3];
console.log(nums.last);  // 3

注意事项

尽管通过申明文件扩大类型定义能够让咱们更灵便地应用类型,但也须要留神一些事项。

申明文件只提供类型信息,不蕴含实现。也就是说,如果咱们为一个类型增加了新的属性或办法,咱们还须要在理论的代码中提供这些属性或办法的实现。

只管 TypeScript 容许咱们为内置类型增加自定义的属性和办法,但这并不意味着这是一个好的做法。在很多状况下,适度批改内置类型可能会导致代码难以了解和保护。因而,咱们应该审慎应用这种个性,尽可能地遵循库或语言的原始设计。

当咱们在一个我的项目中应用多个申明文件时,须要留神文件的加载程序和作用域问题。因为申明文件中的类型申明会影响整个我的项目,所以咱们须要确保所有的申明文件都被正确地加载,并且不会互相冲突。

为第三方库创立申明文件

当咱们在应用第三方库时,通常会遇到不足类型申明的状况。咱们能够通过创立一个申明文件来为该库增加类型申明,以便在 TypeScript 代码中应用该库的时候取得类型检查和主动实现的反对。

假如咱们应用的是一个名为 axios 的库,它是一个风行的用于发动 HTTP 申请的库。假如 axios 库没有提供类型申明文件,咱们能够创立一个申明文件 axios.d.ts 来为它增加类型申明:

declare module 'axios' {
  export interface AxiosRequestConfig {
    url: string;
    method?: string;
    data?: any;
    headers?: any;
  }

  export interface AxiosResponse<T = any> {
    data: T;
    status: number;
    statusText: string;
    headers: any;
    config: AxiosRequestConfig;
  }

  export function request<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
  export function get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
  export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
  // ... 其余申请办法的类型申明 ...
}

在这个申明文件中,咱们应用 declare module 来申明一个名为 axios 的模块,并在其中定义了与 axios 相干的类型申明。

咱们定义了 AxiosRequestConfig 接口,它形容了发动申请时的配置选项;定义了 AxiosResponse 接口,它形容了申请返回的响应数据的构造。

而后,咱们通过 export 关键字将 requestgetpost 等函数导出为模块的公共 API,以便在其余文件中应用这些函数。

当初,在咱们的 TypeScript 代码中,咱们能够通过导入 axios 模块来应用这些类型申明,以及应用 axios 库的办法:

import axios, {AxiosResponse, AxiosRequestConfig} from 'axios';

const config: AxiosRequestConfig = {
  url: 'https://api.example.com',
  method: 'GET',
};

axios.get(config)
  .then((response: AxiosResponse) => {console.log(response.data);
  })
  .catch((error) => {console.error(error);
  });

通过这种形式,咱们能够为第三方库创立申明文件,并在 TypeScript 代码中应用它们来取得类型检查和主动实现的反对,进步代码的可靠性和开发效率。

退出移动版