【前端】深入浅出 - TypeScript 的详细讲解

TypeScript 是一种静态类型编程语言,它是 JavaScript 的超集,添加了类型系统和编译时检查。TypeScript 的主要目标是提高大型项目的开发效率和可维护性。本文将详细介绍 TypeScript 的核心概念、语法、类型系统、高级特性以及最佳实践。
在这里插入图片描述

1. TypeScript 基础
1.1 什么是 TypeScript

TypeScript 是由 Microsoft 开发的一种开源编程语言,它扩展了 JavaScript,增加了静态类型系统和类、接口等面向对象的特性。TypeScript 代码在编译时会被转换为纯 JavaScript 代码,可以在任何支持 JavaScript 的环境中运行。

1.2 安装 TypeScript

要开始使用 TypeScript,首先需要安装 TypeScript 编译器。可以通过 npm(Node.js 包管理器)来安装:

npm install -g typescript

安装完成后,可以使用 tsc 命令来编译 TypeScript 文件:

tsc myFile.ts
1.3 基本语法

TypeScript 的基本语法与 JavaScript 非常相似,但增加了一些类型注解。

1.3.1 变量声明

在 TypeScript 中,可以使用 letconst 关键字来声明变量,并指定其类型。

let message: string = "Hello, TypeScript!";
const pi: number = 3.14;
1.3.2 函数声明

函数可以有参数类型和返回类型注解。

function add(a: number, b: number): number {
  return a + b;
}
1.3.3 类型推断

TypeScript 支持类型推断,编译器可以根据赋值语句推断变量的类型。

let message = "Hello, TypeScript!"; // 类型推断为 string
2. 类型系统
2.1 基本类型

TypeScript 支持以下基本类型:

  • boolean
  • number
  • string
  • null
  • undefined
  • any
  • void
  • never
  • object
  • array
  • tuple
  • enum
2.1.1 数组

数组类型可以通过在元素类型后面加上 [] 来表示。

let numbers: number[] = [1, 2, 3];
2.1.2 元组

元组是具有固定类型的数组。

let tuple: [string, number] = ["TypeScript", 2012];
2.1.3 枚举

枚举类型用于定义一组命名的常量。

enum Color { Red, Green, Blue }
let color: Color = Color.Red;
2.2 复杂类型
2.2.1 对象类型

可以使用接口(Interface)或类型别名(Type Alias)来定义对象类型。

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

type Person = {
  name: string;
  age: number;
};

let person: Person = { name: "Alice", age: 30 };
2.2.2 泛型

泛型允许你在定义函数、接口或类的时候,不预先指定具体类型,而在使用的时候再指定类型。

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

let result = identity<string>("Hello");
2.3 联合类型和交叉类型
2.3.1 联合类型

联合类型表示一个值可以是几种类型之一。

let value: string | number = "Hello";
value = 42;
2.3.2 交叉类型

交叉类型是将多个类型合并为一个类型。

interface A {
  a: string;
}

interface B {
  b: number;
}

let ab: A & B = { a: "Hello", b: 42 };
3. 高级特性
3.1 类和接口
3.1.1 类

TypeScript 支持类,可以定义属性、方法和构造函数。

class Animal {
  name: string;

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

  move(distance: number = 0) {
    console.log(`${this.name} moved ${distance}m.`);
  }
}

let dog = new Animal("Dog");
dog.move(10);
3.1.2 接口

接口用于定义对象的结构。

interface Animal {
  name: string;
  move(distance: number): void;
}

class Dog implements Animal {
  name: string;

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

  move(distance: number) {
    console.log(`${this.name} moved ${distance}m.`);
  }
}

let dog: Animal = new Dog("Buddy");
dog.move(10);
3.2 装饰器

装饰器是一种特殊类型的声明,可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 这种形式,其中 expression 求值为一个函数,该函数会在运行时被调用,被装饰的声明信息做为参数传入。

3.2.1 类装饰器

类装饰器用于修改或增强类的行为。

function readonly(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  descriptor.writable = false;
}

class Example {
  @readonly
  name: string = "Example";

  @readonly
  getName(): string {
    return this.name;
  }
}

let example = new Example();
console.log(example.getName()); // Output: Example
example.name = "NewName"; // TypeError: Cannot assign to read only property 'name' of object '#<Example>'
3.2.2 方法装饰器

方法装饰器用于修改或增强类的方法。

function enumerable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.enumerable = value;
  };
}

class Example {
  @enumerable(false)
  getName(): string {
    return "Example";
  }
}

for (let key in new Example()) {
  console.log(key); // No output
}
3.3 模块

模块用于组织和封装代码,防止命名冲突。

3.3.1 导入和导出

可以使用 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;
}

// app.ts
import { add, subtract } from './math';

console.log(add(1, 2)); // Output: 3
console.log(subtract(5, 3)); // Output: 2
3.3.2 默认导出

可以使用 default 关键字来导出默认值。

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

// app.ts
import add from './math';

console.log(add(1, 2)); // Output: 3
4. 类型推断和类型断言
4.1 类型推断

TypeScript 可以根据上下文自动推断变量的类型。

let message = "Hello, TypeScript!"; // 类型推断为 string
4.2 类型断言

类型断言允许你覆盖编译器的类型推断,强制指定一个类型。

let someValue: any = "This is a string";

let strLength: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length;
5. 工具类型

TypeScript 提供了一些内置的工具类型,用于在类型级别进行操作。

5.1 keyof

keyof 操作符用于获取对象类型的所有键的联合类型。

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

type K = keyof Person; // "name" | "age"
5.2 typeof

typeof 操作符用于获取变量的类型。

let message: string = "Hello, TypeScript!";
type MessageType = typeof message; // string
5.3 Pick

Pick 工具类型用于从一个类型中选择一部分属性。

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

type NameAndAge = Pick<Person, "name" | "age">;
5.4 Record

Record 工具类型用于创建一个对象类型,其键和值的类型分别为两个参数。

type PageInfo = Record<string, string>;

let page: PageInfo = {
  title: "Home",
  url: "/",
};
6. 配置文件

TypeScript 项目通常使用 tsconfig.json 文件来配置编译选项。

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
6.1 常用编译选项
  • target:指定编译后的 JavaScript 版本。
  • module:指定模块系统的类型。
  • strict:启用严格类型检查。
  • esModuleInterop:允许从 CommonJS 模块中导入 ES 模块。
  • outDir:指定编译输出目录。
  • include:指定包含的文件路径。
  • exclude:指定排除的文件路径。
7. 最佳实践
7.1 保持类型一致性

在大型项目中,保持类型的一致性非常重要。可以通过定义通用的接口和类型别名来确保类型的一致性。

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

function createUser(user: User): User {
  // ...
}
7.2 使用严格模式

启用严格模式可以捕获更多的类型错误,提高代码质量。

{
  "compilerOptions": {
    "strict": true
  }
}
7.3 使用 TypeScript 与框架结合

TypeScript 可以与各种前端框架和库结合使用,如 React、Vue 和 Angular。这些框架和库通常提供了 TypeScript 的类型定义文件,可以方便地进行类型检查。

7.3.1 React with TypeScript
import React from 'react';

interface Props {
  name: string;
}

const HelloWorld: React.FC<Props> = ({ name }) => {
  return <div>Hello, {name}!</div>;
};

export default HelloWorld;
7.3.2 Vue with TypeScript
<template>
  <div>Hello, {{ name }}!</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

interface Props {
  name: string;
}

export default defineComponent({
  props: {
    name: {
      type: String,
      required: true,
    },
  },
  setup(props: Props) {
    return {
      name: props.name,
    };
  },
});
</script>
8. 示例代码

以下是一些综合示例,展示了如何在 TypeScript 中使用不同的特性和最佳实践。

8.1 基本类型和函数
let message: string = "Hello, TypeScript!";
let pi: number = 3.14;

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

console.log(add(1, 2)); // Output: 3
8.2 类和接口
interface Animal {
  name: string;
  move(distance: number): void;
}

class Dog implements Animal {
  name: string;

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

  move(distance: number) {
    console.log(`${this.name} moved ${distance}m.`);
  }
}

let dog: Animal = new Dog("Buddy");
dog.move(10);
8.3 泛型
function identity<T>(arg: T): T {
  return arg;
}

let result = identity<string>("Hello");
console.log(result); // Output: Hello
8.4 装饰器
function readonly(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  descriptor.writable = false;
}

class Example {
  @readonly
  name: string = "Example";

  @readonly
  getName(): string {
    return this.name;
  }
}

let example = new Example();
console.log(example.getName()); // Output: Example
example.name = "NewName"; // TypeError: Cannot assign to read only property 'name' of object '#<Example>'
8.5 模块
// math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function subtract(a: number, b: number): number {
  return a - b;
}

// app.ts
import { add, subtract } from './math';

console.log(add(1, 2)); // Output: 3
console.log(subtract(5, 3)); // Output: 2
9. 总结

TypeScript 是一种强大的静态类型编程语言,它扩展了 JavaScript,增加了类型系统和类、接口等面向对象的特性。通过理解 TypeScript 的核心概念、语法、类型系统、高级特性以及最佳实践,开发者可以更高效地使用 TypeScript 构建高质量的大型项目。本文详细讲解了 TypeScript 的各个方面,希望对你理解和使用 TypeScript 有所帮助。

附录

  • TypeScript 官方文档:TypeScript 文档
  • TypeScript Playground:TypeScript Playground
  • MDN Web 文档:TypeScript 简介

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/915599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

查询DBA_FREE_SPACE缓慢问题

这个是一个常见的问题&#xff0c;理论上应该也算是一个bug&#xff0c;在oracle10g&#xff0c;到19c&#xff0c;我都曾经遇到过&#xff1b;今天在给两套新建的19C RAC添加监控脚本时&#xff0c;又发现了这个问题&#xff0c;在这里记录一下。 Symptoms 环境&#xff1a;…

The Internals of PostgreSQL 翻译版 持续更新...

为了方便自己快速学习&#xff0c;整理了翻译版本&#xff0c;目前翻译的还不完善&#xff0c;后续会边学习边完善。 文档用于自己快速参考&#xff0c;会持续修正&#xff0c;能力有限,无法确保正确!!! 《The Internals of PostgreSQL 》 不是 《 PostgreSQL14 Internals 》…

机器学习 ---模型评估、选择与验证(1)

目录 前言 一、为什么要有训练集与测试集 1、为什么要有训练集与测试集 2、如何划分训练集与测试集 二、欠拟合与过拟合 1、什么是欠拟合与欠拟合的原因 2、什么是过拟合与过拟合的原因 一些解决模型过拟合和欠拟合问题的常见方法&#xff1a; 解决过拟合问题&#…

一文简单了解Android中的input流程

在 Android 中&#xff0c;输入事件&#xff08;例如触摸、按键&#xff09;从硬件传递到应用程序并最终由应用层消费。整个过程涉及多个系统层次&#xff0c;包括硬件层、Linux 内核、Native 层、Framework 层和应用层。我们将深入解析这一流程&#xff0c;并结合代码逐步了解…

【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题

目录 1. 单例模式 (1) 饿汉模式 (2) 懒汉模式 1. 单线程版本 2. 多线程版本 2. 解决懒汉模式产生的线程安全问题 (1) 产生线程安全的原因 (2) 解决线程安全问题 1. 通过加锁让读写操作紧密执行 方法一 方法二 2. 处理加锁引入的新问题 问题描述 …

二叉树搜索树(下)

二叉树搜索树&#xff08;下&#xff09; 二叉搜索树key和key/value使用场景 key搜索场景 只有key作为关键码&#xff0c;结构中只需要存储key即可&#xff0c;关键码即为需要搜索到的值&#xff0c;搜索场景只需要判断 key在不在。key的搜索场景实现的二叉树搜索树支持增删查…

Web项目版本更新及时通知

背景 单页应用&#xff0c;项目更新时&#xff0c;部分用户会出更新不及时&#xff0c;导致异常的问题。 技术方案 给出版本号&#xff0c;项目每次更新时通知用户&#xff0c;版本已经更新需要刷新页面。 版本号更新方案版本号变更后通知用户哪些用户需要通知&#xff1f;…

D64【python 接口自动化学习】- python基础之数据库

day64 SQL-DQL-基础查询 学习日期&#xff1a;20241110 学习目标&#xff1a;MySQL数据库-- 133 SQL-DQL-基础查询 学习笔记&#xff1a; 基础数据查询 基础数据查询-过滤 总结 基础查询的语法&#xff1a;select 字段列表|* from 表过滤查询的语法&#xff1a;select 字段…

Unity插件-Smart Inspector 免费的,接近虚幻引擎的蓝图Tab管理

习惯了虚幻的一张蓝图&#xff0c;关联所有Tab &#xff08;才发现Unity&#xff0c;的Component一直被人吐槽&#xff0c;但实际上是&#xff1a;本身结构Unity 的GameObject-Comp结构&#xff0c;是好的不能再好了&#xff0c;只是配上 smart Inspector就更清晰了&#xff0…

2024 年Postman 如何安装汉化中文版?

2024 年 Postman 的汉化中文版安装教程

单元测试、集成测试、系统测试、验收测试、压力测试、性能测试、安全性测试、兼容性测试、回归测试(超详细的分类介绍及教学)

目录 1.单元测试 实现单元测试的方法&#xff1a; 注意事项&#xff1a; 2.集成测试 需注意事项&#xff1a; 实现集成测试的方法&#xff1a; 如何实现高效且可靠的集成测试&#xff1a; 3.系统测试 实现系统测试的方法: 须知注意事项&#xff1a; 4.验收测试 实现验…

MySQL 忘记 root 密码,使用跳过密码验证进行登录

操作系统版本&#xff1a;CentOS 7 MySQL 忘记 root 密码&#xff0c;使用跳过密码验证进行登录 修改 /etc/my.cnf 配置文件&#xff0c;在 [mysqld] 后面任意一行添加 skip-grant-tables vim /etc/my.cnf 重启 MySQL systemctl restart mysqld 登录 MySQL&#xff08;无 -…

3D Web渲染引擎HOOPS Communicator:助力企业打造定制化3D可视化产品的强大工具

HOOPS Communicator为开发人员提供了多样化的定制手段&#xff0c;使其在3D网页可视化领域保持领先地位。很多潜在客户都关心如何利用HOOPS Communicator将其打造成自己产品的独特解决方案。展示我们现有合作伙伴的成功案例正是分享此信息的最佳方式。 每家合作伙伴都在产品中…

【stablediffusion】阿里发布新ID保持项目EcomID, 可从单个ID参考图像生成定制的保ID图像,ComfyUI可使用。

今天&#xff0c;我们将向您介绍一款令人兴奋的更新——阿里发布的ID保持项目EcomID。这是一款基于Stable Diffusion技术的AI绘画工具&#xff0c;旨在为您提供一键式生成高质量保ID图像的便捷体验。无论您是AI绘画的新手还是专业人士&#xff0c;这个工具都能为您带来极大的便…

计算机网络(11)和流量控制补充

这一篇对数据链路层中的和流量控制进行详细学习 流量控制&#xff08;Flow Control&#xff09;是计算机网络中确保数据流平稳传输的技术&#xff0c;旨在防止数据发送方发送过多数据&#xff0c;导致接收方的缓冲区溢出&#xff0c;进而造成数据丢失或传输失败。流量控制通常…

【VLANPWN】一款针对VLAN的安全研究和渗透测试工具

关于VLANPWN VLANPWN是一款针对VLAN的安全研究和渗透测试工具&#xff0c;该工具可以帮助广大研究人员通过对VLAN执行渗透测试&#xff0c;来研究和分析目标VLAN的安全状况。该工具专为红队研究人员和安全学习爱好者设计&#xff0c;旨在训练网络工程师提升网络的安全性能&…

ES6代理和反射新特性,详细讲解

代理与反射 es6新增了代理和反射特性&#xff0c;这两个特性为开发者提供了拦截并向基本操作嵌入额外行为的能力。 代理基础 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta charset"UTF-8"&g…

MYSQL 精通索引【快速理解】

目录 1、什么是索引&#xff1f; 2、索引结构 1.为什么不使用二叉树呢&#xff1f; 2.B树数据结果 3.B树 4.Hash结构 3、索引语法 1.创建索引 2.查看索引 3.删除索引 4、SQL性能分析 1.SQL执行频次 2.慢查询日志 3.profile详情 4.EXPLAIN 5、索引规则 1.最左前缀法则 2.索…

光驱验证 MD5 校验和

步骤 1&#xff1a;在 Ubuntu 上打包文件并生成 MD5 校验和 打包文件 使用 tar 命令将文件夹打包成 tar.gz 文件&#xff1a; tar -czvf my_files.tar.gz /path/to/folder 生成 MD5 校验和 使用 md5sum 命令生成打包文件的 MD5 校验和&#xff1a; md5sum my_files.tar.g…

《网络数据安全管理条例》将于2025年1月1日起正式施行,从业者应如何解读?

2024年9月&#xff0c;国务院总理李强签署国务院令&#xff0c;公布了《网络数据安全管理条例》&#xff08;以下简称《条例》&#xff09;&#xff0c;该条例将于2025年1月1日起正式施行。 这一条例的出台&#xff0c;标志着我国在网络数据安全领域的管理迈上了新的台阶&#…