Node.js通用计算15--TypeScript介绍

本篇文章几乎全部由大语言模型(QWen3:8b)生成,本文主要目的是为了形成一个关于TS的快速查阅资料,对本人来说,装饰器那段有点过于拗口,各位看官请酌情观看.

一、TypeScript概述

JavaScript 作为一门动态类型语言,在开发大型应用时容易出现以下问题:

  • 类型错误难以发现:运行时错误可能导致调试成本高。
  • 代码可维护性差:缺乏类型定义,团队协作时容易理解代码逻辑。
  • 缺乏工具支持:IDE 无法提供精准的代码提示和重构支持。
    TypeScript 的诞生正是为了解决这些问题,它是由微软开发的一种开源编程语言,它是 JavaScript 的超集,在 JavaScript 的基础上添加了 静态类型、类型推断、接口、泛型 等高级特性。它由 Dmitry A. Soshnikov 和 Anders Hejlsberg(C# 和 Visual Studio 的架构师)共同设计,旨在解决 JavaScript 在大型项目中常见的维护性、可读性和错误排查困难等问题。TypeScript 的核心价值在于 "类型安全" 和 "开发体验优化"。它通过静态类型检查减少运行时错误,结合现代 JavaScript 特性(如 ES6+),使开发者能够构建更可靠、可维护的代码。随着前端和后端开发的复杂化,TypeScript 已成为现代 Web 开发的主流选择之一。

1. 核心特性

  • 静态类型系统:开发者可以为变量、函数参数、返回值等定义明确的类型,编译器会在编译时检查类型是否匹配。
  • 类型推断:即使不显式声明类型,TypeScript 也能通过上下文推断出变量类型(例如 let x = 10; 会被推断为 number)。
  • 接口(Interfaces):定义对象的结构,用于类型检查和抽象设计。
  • 泛型(Generics):编写可复用的组件,支持多种数据类型。
  • 装饰器(Decorators):用于增强类、方法、参数等的元编程能力(如添加日志、验证等)。
  • 模块系统:支持模块化开发,便于代码组织和复用。

2. 编译与运行

TypeScript 代码需要通过 TypeScript 编译器(tsc) 转换为 JavaScript,因为浏览器和 Node.js 仅支持 JavaScript。编译过程会检查类型错误,并生成兼容的 JavaScript 代码(如 ES5、ES6 等)。最终的 JavaScript 代码可以在任何支持 JS 的环境中运行。

3. 应用场景

  • 大型前端项目:如 React、Vue、Angular 等框架广泛支持 TypeScript,帮助开发者构建可维护的复杂应用。
  • 后端开发:Node.js 项目中使用 TypeScript 可提升代码的可读性和健壮性。
  • API 接口定义:通过接口明确数据结构,确保前后端交互的准确性。
  • 工具库开发:泛型和类型系统使工具库更灵活、可扩展。

4. 生态与工具

IDE 支持:VS Code、WebStorm 等编辑器提供智能提示、代码补全、类型检查等功能。

TypeScript Playground:在线编辑器,可实时测试 TypeScript 代码。

社区与资源:丰富的文档、教程、开源项目和社区支持,帮助开发者快速上手。

二、基础类型系统

1. 基本类型

TS语言支持一下数据类型。

类型 描述 示例
boolean 表示布尔值,取值为 truefalse let isDone: boolean = false;
number 表示数字(包括整数和浮点数) let decimal: number = 6.4;
string 表示字符串(Unicode字符序列) let name: string = "Alice";
null 表示空值,通常用于表示变量未赋值 let empty: null = null;
undefined 表示变量未赋值 let value: undefined;
symbol 表示唯一标识符(常用于对象属性键) let key: symbol = Symbol("key");
void 表示函数没有返回值 function log(message: string): void { console.log(message); }
any 表示任意类型(类型检查被绕过) let x: any = "hello";
array 表示数组类型(使用方括号表示) let list: number[] = [1, 2, 3];
tuple 表示固定长度的元组类型(指定元素类型和顺序) let point: [number, string] = [42, "hello"]
enum 表示枚举类型(命名的常量集合) enum Color { Red, Green, Blue }

2. 类型推断

TS支持静态类型推断

typescript 复制代码
let score = 95; // TypeScript 会自动推断为 number 类型

3.空值类型

typescript 复制代码
function warn(message: string | null): void {
  if (message) {
    console.log(message);
  } else {
    console.log("No message");
  }
}

4. 类型断言

指定某个变量的类型

typescript 复制代码
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

三、泛型 (Generics)

泛型是一种参数化类型的机制,允许你编写与类型无关的代码,在使用时再指定具体的类型。它类似于数学中的"占位符",在编译时会根据实际传入的类型进行类型检查和优化。

typescript 复制代码
// 普通函数(只能处理特定类型)
function printArray(arr: number[]) {
  arr.forEach(item => console.log(item));
}

// 使用泛型的函数(可以处理任意类型)
function printArray<T>(arr: T[]) {
  arr.forEach(item => console.log(item));
}

1. 泛型函数

typescript 复制代码
function identity<T>(arg: T): T {
  return arg;
}

2.泛型类

typescript 复制代码
class Box<T> {
  contents: T;
  constructor(value: T) {
    this.contents = value;
  }
  
  getContents(): T {
    return this.contents;
  }
}

3.泛型接口

typescript 复制代码
interface Pair<T> {
  first: T;
  second: T;
}

4.泛型约束

泛型约束(Generic Constraints)是指通过限制泛型参数的类型范围,确保在使用泛型时,类型满足特定条件(如必须具有某些属性或方法)。通过约束,可以避免类型错误,并增强代码的类型安全性。

typescript 复制代码
interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length); // OK
  return arg;
}

可以使用 & 操作符为泛型参数添加多个约束:

typescript 复制代码
function example<T extends string & { id: number }>(arg: T): void {
  console.log(arg.id); // 安全访问 id 属性
}

可以为泛型参数指定默认约束:

typescript 复制代码
function example<T extends string = string>(arg: T): void {
  console.log(arg.length); // string 有 length 属性
}

四、装饰器 (Decorators)

装饰器是 TypeScript 中的一种元编程特性,它允许开发者在不修改原始代码 的情况下,向类、方法、属性或参数添加额外的功能或修改。装饰器本质上是一个函数 ,它接收被装饰的类或成员作为参数,并返回一个修改后的类或成员。装饰器有以下几类

类装饰器(Class Decorator):

方法装饰器(Method Decorator):

属性装饰器(Property Decorator):

参数装饰器(Parameter Decorator):

1.类装饰器

类装饰器作用于类,可以修改类的结构,例如添加属性、方法等。

typescript 复制代码
function Component<T>(target: Function): T | void {
  target.isComponent = true;
  return target;
}

@Component()
class MyComponent {
  // ...
}

2. 方法装饰器

方法装饰器作用于类的方法,可以修改方法的行为。

typescript 复制代码
function Log(target: any, key: string, descriptor: PropertyDescriptor): PropertyDescriptor {
  const originalMethod = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log(`Calling ${key} with`, args);
    return originalMethod.apply(this, args);
  };
  return descriptor;
}

class MyClass {
  @Log
  greet(message: string) {
    console.log(message);
  }
}

3.属性装饰器

属性装饰器作用于类的属性,可以用来修改属性的类型、值等。

typescript 复制代码
function MinValue(min: number) {
  return (target: any, key: string) => {
    let value = target[key];
    if (value < min) {
      throw new Error(`Value must be at least ${min}`);
    }
  };
}

class MyClass {
  @MinValue(10)
  value: number = 5;
}

4. 参数装饰器

参数装饰器作用于类的方法或属性的参数,可以用来修改参数的行为。

typescript 复制代码
function Required(target: any, key: string, index: number) {
  console.log(`Parameter ${index} of method ${key} is required`);
}

class MyClass {
  greet(@Required message: string) {
    console.log(message);
  }
}

5.装饰器的执行顺序

当多个装饰器作用于同一个目标时,它们按照从上到下的顺序应用,但执行顺序是从下到上(先执行后写的装饰器)。

五、接口 (Interfaces)

1. 什么是接口?

在 TypeScript 中,接口(Interface) 是一种定义对象结构的类型。它描述了一个对象应该具有的属性、方法、索引签名 和 类型,但不提供具体的实现。接口主要用于类型检查,确保对象符合预定义的结构。接口是 TypeScript 中实现面向对象编程的重要概念,它帮助开发者明确类、对象、函数等的契约,提高代码的可读性和可维护性,它提供了以下优势:

** 类型安全:确保对象结构符合预期。**

** 代码清晰:明确表达代码的契约和意图。**

** 可维护性:通过接口隔离变化,提高代码的灵活性。**

** 文档作用:作为代码设计的文档,帮助理解接口的设计意图。**

** 在实际开发中,应合理使用接口,避免过度设计,同时注意与类型别名的区别,根据具体场景选择合适的方式。**

2.接口的基本用法

** 定义接口**

使用 interface 关键字定义接口:

typescript 复制代码
interface User {
  id: number;
  name: string;
  email?: string; // 可选属性
}

实现接口

类或对象可以通过显式实现或隐式实现接口:

typescript 复制代码
class UserImpl implements User {
  id: number;
  name: string;
  
  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }
}

接口的类型检查

TypeScript 编译器会检查实现接口的对象是否满足接口定义的所有属性和方法:

typescript 复制代码
const user: User = {
  id: 1,
  name: "Alice"
  // email: "alice@example.com" // 可选属性,可以省略
};

// 编译器会报错,因为对象缺少 id 和 name 属性
const invalidUser: User = {
  age: 25 // 错误:缺少 id 和 name
};

2.接口的高级特性

泛型与接口加粗样式

接口可以结合泛型,使定义更灵活:

typescript 复制代码
interface KeyValuePair<K, V> {
  key: K;
  value: V;
}
const pair: KeyValuePair<number, string> = { key: 1, value: "hello" };

**可选属性与只读属性 **

可选属性:使用 ? 定义属性是否可选。

只读属性:使用 readonly 关键字定义属性不可修改。

typescript 复制代码
interface Point {
  readonly x: number; // 只读属性
  y?: number; // 可选属性
}

索引签名

接口可以通过索引签名定义数组或其他映射类型的结构:

typescript 复制代码
interface Dictionary {
  [key: string]: number;
}

const dict: Dictionary = {
  a: 1,
  b: 2
};

类型约束

在接口中,可以使用泛型约束来限制属性类型:

typescript 复制代码
interface Lengthwise<T extends { length: number }> {
  length: number;
}

function getLength<T extends Lengthwise<T>>(obj: T): number {
  return obj.length;
}

** 扩展接口 **

使用 extends 关键字扩展已有接口:

typescript 复制代码
interface User {
  id: number;
  name: string;
}

interface UserWithEmail extends User {
  email: string;
}

const user: UserWithEmail = {
  id: 1,
  name: "Alice",
  email: "alice@example.com"
};

接口与类型别名

在 TypeScript 中,接口 和 类型别名(type) 很相似,但它们有一些区别:

定义结构:两者都可以定义对象结构。

合并:接口可以被多次扩展(extends),而类型别名不能。

重写:接口不能重写,而类型别名可以重写。

静态成员:接口不能定义静态成员,而类型别名可以。

示例:

typescript 复制代码
// 类型别名
type User = {
  id: number;
  name: string;
};

// 接口
interface User {
  id: number;
  name: string;
}

4.实际应用场景

函数参数类型

typescript 复制代码
interface Options {
  verbose?: boolean;
}

function configure(options: Options) {
  // ...
}

类实现

typescript 复制代码
interface Car {
  start(): void;
  stop(): void;
}

class Tesla implements Car {
  start() {
    console.log("Starting Tesla");
  }
  
  stop() {
    console.log("Stopping Tesla");
  }
}

库中的类型定义

typescript 复制代码
interface Promise<T> {
  then<U>(onfulfilled?: (value: T) => U): Promise<U>;
// 使用内置的 Promise 类型
}
相关推荐
BUG创建者2 小时前
openlayers上跟据经纬度画出轨迹
开发语言·javascript·vue·html
漫随流水2 小时前
HTML和CSS和JavaScript的区别
javascript·css·html
小J听不清2 小时前
CSS 浮动(float)全解析:布局 / 文字环绕 / 清除浮动
前端·javascript·css·html·css3
wuhen_n2 小时前
生产环境极致优化:拆包、图片压缩、Gzip/Brotli 完全指南
前端·javascript·vue.js
a1117762 小时前
Three.js 3D模型动画展示项目(开源)
开发语言·javascript·ecmascript
Wect2 小时前
LeetCode 918. 环形子数组的最大和:两种解法详解
前端·算法·typescript
滴滴答答哒2 小时前
layui响应式表单上下结构
前端·javascript·layui
light blue bird2 小时前
MES/ERP的Web多页签报表系统
数据库·node.js·ai大数据·mes/erp·web报表
小J听不清3 小时前
CSS 文本样式全解析:颜色 / 对齐 / 装饰 / 缩进
前端·javascript·css·html·css3