亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

TypeScript高級知識入門教程

標簽:
Typescript
概述

本文深入探讨了TypeScript高级知识,包括泛型、高级类型特性、装饰器应用和模块化编程等内容。文章还提供了类型推断与类型断言的最佳实践以及项目结构建议,并详细解释了TypeScript配置文件的使用方法。通过这些内容,读者可以掌握编写高效且安全TypeScript代码的关键技巧。

TypeScript高级知识入门教程
TypeScript 基础回顾

变量声明与类型注解

TypeScript 是 JavaScript 的一个超集,它添加了静态类型检查,使代码更安全且易于维护。在 TypeScript 中,变量声明时需要指定类型,这有助于开发人员和编译器更好地理解代码意图。

下面是一个简单的变量声明示例:

let num: number = 42;
const message: string = "Hello, TypeScript!";
let isTrue: boolean = true;

console.log(num, message, isTrue);

函数定义与调用

在 TypeScript 中,函数的定义需要明确指定返回类型和参数类型。这有助于在编译时进行类型检查,防止类型错误。

例如:

function add(a: number, b: number): number {
    return a + b;
}

let result: number = add(10, 20);
console.log(result); // 输出 30

类与接口简介

TypeScript 中的类和接口是创建自定义类型的主要工具。类用于定义对象和它们的行为,而接口用于定义对象的结构。

下面是一个简单的类和接口的示例:

interface Person {
    name: string;
    age: number;
}

class Student implements Person {
    name: string;
    age: number;
    grade: string;

    constructor(name: string, age: number, grade: string) {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
}

let student: Person = new Student("Alice", 20, "A");
console.log(student.name, student.age); // 输出 Alice 20
泛型详解

泛型的基本概念

泛型是一种可以接受任意类型的编程模式,它允许创建可以处理多种数据类型的通用代码。泛型通常在函数、类和接口中使用,使代码更具灵活度和重用性。

下面是一个简单的泛型函数示例:

function first<T>(arr: T[]): T {
    return arr[0];
}

let numbers: number[] = [1, 2, 3];
console.log(first(numbers)); // 输出 1

let strings: string[] = ["a", "b", "c"];
console.log(first(strings)); // 输出 a

在函数中的应用

泛型在函数中应用广泛,它可以处理不同类型的数据。例如,一个函数可能需要返回数组的第一个元素,但这个数组可以是任何类型的数据。

function last<T>(arr: T[]): T {
    return arr[arr.length - 1];
}

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

let strings: string[] = ["a", "b", "c"];
console.log(last(strings)); // 输出 c

在类和接口中的应用

在类和接口中使用泛型可以增强代码的灵活性。例如,一个容器类可以接受任何类型的元素,而接口可以定义一个通用的类型结构。

泛型类示例

class List<T> {
    items: T[] = [];

    add(item: T) {
        this.items.push(item);
    }

    get(index: number): T {
        return this.items[index];
    }
}

let numberList = new List<number>();
numberList.add(1);
numberList.add(2);
console.log(numberList.get(0)); // 输出 1

let stringList = new List<string>();
stringList.add("a");
stringList.add("b");
console.log(stringList.get(0)); // 输出 a

泛型接口示例

interface Item<T> {
    value: T;
    toString(): string;
}

class NumberItem implements Item<number> {
    value: number;

    constructor(value: number) {
        this.value = value;
    }

    toString() {
        return this.value.toString();
    }
}

let numberItem: Item<number> = new NumberItem(42);
console.log(numberItem.toString()); // 输出 42
高级类型特性

联合类型与交叉类型

联合类型

联合类型是指变量可以赋值为多种类型中的一种。例如,一个变量可以是字符串或数字类型。

let value: number | string;
value = 42;
value = "Hello, TypeScript!";

console.log(value); // 输出 Hello, TypeScript!

交叉类型

交叉类型是指将两个或多个接口合并成一个新的接口。这可以用于组合多个接口的属性和方法。

interface Person {
    name: string;
}

interface Employee {
    id: number;
}

type PersonEmployee = Person & Employee;

let personEmployee: PersonEmployee = {
    name: "Alice",
    id: 123
};

console.log(personEmployee.name, personEmployee.id); // 输出 Alice 123

映射类型

映射类型是一种高级类型特性,可以用来创建新的类型。它通常用于为现有类型中的每个属性创建新的类型。

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

interface User {
    id: number;
    email: string;
}

let readonlyUser: Readonly<User> = {
    id: 123,
    email: "[email protected]"
};

// readonlyUser.id = 456; // 编译错误,因为 id 是只读属性
console.log(readonlyUser.id, readonlyUser.email); // 输出 123 [email protected]

条件类型

条件类型是基于类型条件创建新类型的机制。它们通常用于条件地推导类型。

type IsString<T> = T extends string ? true : false;

let isString1: IsString<string>; // 输出 true
let isString2: IsString<number>; // 输出 false
模块化编程

模块的基本概念

TypeScript 支持两种模块化编程的模式:CommonJS 和 ES 模块。这两种模式允许将代码组织成独立的模块,便于管理和维护。

导入与导出机制

在模块化编程中,需要使用 importexport 语句来组织代码。下面是一个简单的模块示例:

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

export function subtract(a: number, b: number): number {
    return a - b;
}
// main.ts
import { add, subtract } from "./math";

console.log(add(10, 5)); // 输出 15
console.log(subtract(10, 5)); // 输出 5

ES 模块与 CommonJS 模块的区别

ES 模块使用 .js.ts 文件扩展名,并使用 importexport 语句。CommonJS 模块使用 .js 文件扩展名,并使用 requiremodule.exports

// esModule.ts
export const message = "Hello, ES Module!";

// commonjsModule.ts
module.exports = {
    message: "Hello, CommonJS Module!"
};

使用 ES 模块:

// mainES.ts
import { message } from "./esModule";

console.log(message); // 输出 Hello, ES Module!

使用 CommonJS 模块:

// mainCommonJS.ts
const { message } = require("./commonjsModule");

console.log(message); // 输出 Hello, CommonJS Module!
装饰器应用

装饰器的基本概念

装饰器是一种特殊的声明,可以附加到类声明、方法、访问器、属性或参数。装饰器通常用于元编程,如在运行时修改或增强代码。

下面是一个简单的装饰器示例:

function log(target: any, key: string) {
    console.log(`Accessing ${key} property`);
}

class User {
    @log
    name: string = "Alice";
}

let user = new User();
console.log(user.name); // 输出 Accessing name property Alice

装饰器工厂

装饰器工厂允许传递参数来创建装饰器。这种方式使得装饰器更加灵活和可复用。

function log(message: string) {
    return function (target: any, key: string) {
        console.log(`${message} ${key} property`);
    };
}

class User {
    @log("Accessing")
    name: string = "Alice";
}

let user = new User();
console.log(user.name); // 输出 Accessing name property Alice

常见装饰器类型

  • @ClassDecorator 用于类声明
  • @MethodDecorator 用于方法声明
  • @PropertyDecorator 用于属性声明
  • @ParameterDecorator 用于参数声明

下面是一个更复杂的装饰器示例,包括类装饰器和方法装饰器:

function classDecorator<T extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
        name: string = "DecoratedInstance";
    };
}

function methodDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
    descriptor.value = function(...args: any[]) {
        console.log(`Calling ${key} with arguments`, args);
        return descriptor.value.apply(this, args);
    };
}

@classDecorator
class User {
    @methodDecorator
    getName() {
        return this.name;
    }
}

let user = new User();
console.log(user.getName()); // 输出 Calling getName with arguments []
代码组织与最佳实践

项目结构建议

推荐的 TypeScript 项目结构可以包括以下部分:

src/
├── models/
│   └── user.ts
├── services/
│   └── userService.ts
├── routes/
│   └── userRoutes.ts
├── utils/
│   └── helpers.ts
└── index.ts

示例代码

user.ts 中:

export class User {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}

userService.ts 中:

import { User } from "../models/user";

export class UserService {
    getUser(id: number): User {
        // 实现获取用户逻辑
        return new User("Alice", 20);
    }
}

userRoutes.ts 中:

import { UserService } from "../services/userService";

export const getUserById = (req, res) => {
    const userService = new UserService();
    const user = userService.getUser(req.params.id);
    res.json(user);
};

helpers.ts 中:

export function log(message: string) {
    console.log(message);
}

index.ts 中:

import { getUserById } from "./routes/userRoutes";

// 启动应用
log("Application started");

类型推断与类型断言

类型推断允许 TypeScript 从代码推断类型,而类型断言则允许显式指定类型。

类型推断示例:

let num = 42; // 类型推断为 number
let message = "Hello, TypeScript!"; // 类型推断为 string

类型断言示例:

let anyVar = "Hello" as string; // 类型断言为 string

function getLength(value: any): number {
    return (value as string).length;
}

console.log(getLength("Hello")); // 输出 5

更多类型推断与类型断言示例:

// 更多类型推断示例
let unknownVar = "Hello"; // 类型推断为 string
let unknownVar2 = 42; // 类型推断为 number

// 更多类型断言示例
let anyVar = "Hello" as string; // 类型断言为 string
let anyVar2 = 42 as number; // 类型断言为 number

function getLength(value: any): number | undefined {
    return (value as string).length;
}

console.log(getLength("Hello")); // 输出 5
console.log(getLength(42)); // 输出 undefined

TypeScript 配置文件详解

TypeScript 配置文件 tsconfig.json 用于指定编译器选项,如输出目录、模块类型和类型检查器行为。

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "outDir": "./dist",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": ["src/**/*.ts"],
    "exclude": ["node_modules"]
}
  • "target": "ES6":编译到 ES6 语法
  • "module": "commonjs":使用 CommonJS 模块
  • "outDir": "./dist":输出目录
  • "strict": true:启用严格类型检查
  • "esModuleInterop": true:允许 CommonJS 和 ES 模块互操作
  • "skipLibCheck": true:跳过库文件的类型检查
  • "forceConsistentCasingInFileNames": true:强制文件名大小写一致

总结,通过以上内容,你可以深入了解 TypeScript 的高级特性和最佳实践。掌握这些知识将帮助你编写更高效、更安全的代码。推荐使用慕课网等平台进行更多深入学习。

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消