您现在的位置是:首页 >其他 >TypeScript学习总结(四)网站首页其他

TypeScript学习总结(四)

叶落风尘 2024-06-14 00:01:02
简介TypeScript学习总结(四)

范型

TS(TypeScript)中的泛型是一种参数化类型的机制,允许在定义函数、类或接口时使用类型变量来表示参数或返回值的类型。通过使用泛型,可以将类型的具体实现留给使用者来决定,从而增加代码的灵活性和复用性。

在 TS 中,可以使用尖括号 <> 将泛型参数放置在函数名或类名后面,例如:

function identity<T>(arg: T): T {
  return arg;
}

class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

在上面的例子中,identity 函数使用了一个类型变量 T 来表示传入参数和返回值的类型,并将该类型变量放在函数名后面的尖括号内。

GenericNumber 类也使用了类型变量 T 来表示其属性 zeroValue 和方法 add 的类型,从而使得该类可以适用于任意类型的数值。

在调用泛型函数或实例化泛型类时,需要在尖括号内指定类型参数的具体类型,例如:

let output = identity<string>("Hello World");
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

上述代码中,通过在 identity 函数和 GenericNumber 类名后的尖括号内指定具体的类型参数,分别得到了一个返回字符串类型的 output 变量和一个处理数字类型的 myGenericNumber 实例。

泛型在接口和类中的使用

在接口中,可以使用泛型来定义一个通用的类型,使其适用于多种类型。例如:

interface MyInterface<T> {
  property: T;
  method(): T;
}

上述代码中,MyInterface 接口使用了泛型 T 来定义 propertymethod() 的返回值类型。这样,当我们实现 MyInterface 接口时,可以指定 T 的具体类型,并保证 propertymethod() 的返回值类型与 T 相同。

在类中,泛型可以用于定义类的属性、方法和构造函数参数类型。例如:

class MyClass<T> {
  private prop: T;

  constructor(arg: T) {
    this.prop = arg;
  }

  public getProp(): T {
    return this.prop;
  }
}

上述代码中,MyClass 类使用了泛型 T 来定义 prop 属性的类型以及构造函数的参数类型。这样,我们可以创建一个 MyClass 实例并传入任何类型的参数,而 prop 属性的类型和 getProp() 方法的返回值类型都将与传入的参数类型相同。

模块化

模块的基本概念

在TypeScript中,模块是指包含代码的独立单元,可以将其导出以供其他模块使用,也可以从其他模块中导入代码。
TypeScript中的模块采用了标准的ES6模块语法,并增加了一些额外的功能,例如命名空间、模块别名等。
在一个TypeScript应用中,每个文件都被视为一个模块,其中定义的变量、函数、类等默认情况下是私有的,如果需要在其他模块中使用,需要使用export关键字将其导出。同时,使用import关键字可以从其他模块中导入代码。

模块导出和引入

模块可以包含变量、函数、类和类型声明等内容,并且可以将它们导出供其他模块使用。

下面是一些常见的模块导出语法:

  1. 导出变量或常量:
export const myVariable = 123;
  1. 导出函数:
export function myFunction() {
  // ...
}
  1. 导出类:
export class MyClass {
  // ...
}
  1. 导出类型声明:
export interface MyInterface {
  // ...
}

模块中的导入语法如下:

  1. 导入默认导出:
import myModule from './myModule';
  1. 导入具名导出:
import { myVariable, myFunction, MyClass } from './myModule';
  1. 导入所有导出:
import * as myModule from './myModule';

需要注意的是,在 ES6 模块系统中,导入和导出都是静态的,这意味着它们只能出现在模块的顶层作用域中,并且不能在函数或语句块中使用。此外,ES6 模块系统也支持循环依赖和动态导入等高级特性,可以更加灵活地组织和加载模块。

默认导出和命名导出
  1. 默认导出

默认导出是指一个模块只能够输出一个值,这个值可以是任意类型的。在一个模块中,通过使用export default关键字来进行默认导出。例如:

// module.ts
export default function add(a: number, b: number): number {
  return a + b;
}

// app.ts
import add from './module';
console.log(add(1, 2)); // 输出 3

在app.ts文件中,我们使用import语句引入了module.ts文件中的默认导出项add函数。注意,在import语句中,我们没有使用花括号{}包含add,这是因为默认导出不需要使用变量名来标识。

  1. 命名导出

命名导出是指一个模块可以输出多个值,每个值都有一个名称。在一个模块中,通过使用export关键字加上标识符来进行命名导出。例如:

// module.ts
export function add(a: number, b: number): number {
  return a + b;
}

export const PI = 3.14;

// app.ts
import { add, PI } from './module';
console.log(add(1, 2)); // 输出 3
console.log(PI); // 输出 3.14

在app.ts文件中,我们使用import语句引入了module.ts文件中的命名导出项add函数和常量PI。注意,在import语句中,我们使用了花括号{}来包含add和PI,这是因为命名导出需要使用变量名来标识。

命名空间

命名空间通过使用关键字 namespace 来定义,可以在一个命名空间内声明变量、函数、类等。例如:

namespace MyNamespace {
  export const message = "Hello World";

  export function sayHello() {
    console.log(message);
  }

  export class Person {
    constructor(public name: string) {}
  }
}

在上面的例子中,我们创建了一个名为 MyNamespace 的命名空间,并在其中声明了一个常量、一个函数和一个类。注意到在命名空间外部无法访问这些成员,因为它们被封装在了命名空间内。

要在命名空间外部使用命名空间中的成员,需要使用 export 关键字进行导出。例如,在下面的代码中,我们可以使用 MyNamespace.messageMyNamespace.Person

import { MyNamespace } from "./my-namespace";

console.log(MyNamespace.message); // 输出 "Hello World"

const person = new MyNamespace.Person("Alice");
console.log(person.name); // 输出 "Alice"
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。