TypeScript 测验(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在 JavaScript 世界中,TypeScript 的出现如同一场静默的革命。它通过静态类型系统和编译时检查,帮助开发者提前发现代码中的逻辑漏洞,降低维护成本。对于编程初学者和中级开发者而言,掌握 TypeScript 的核心概念,不仅能提升代码质量,还能为未来应对复杂项目打下坚实基础。本文将以“TypeScript 测验”的形式,通过知识点解析、代码示例和常见误区分析,带你系统性地梳理 TypeScript 的关键特性。


一、基础类型与类型推断

1.1 基础类型与声明语法

TypeScript 的核心是类型系统。与 JavaScript 不同,TypeScript 要求开发者显式或隐式地为变量、函数参数和返回值指定类型。例如:

let count: number = 0; // 显式声明类型为 number  
let name = "Alice";    // 通过类型推断自动识别为 string  

类型推断是 TypeScript 的智能体现。当变量赋值时,TypeScript 会自动推断其类型,但若初始值为空(如 let empty),则会报错。

比喻:类型推断如同“侦探”角色,它通过已有线索(初始值)推断变量的“身份”(类型),但若线索不足,则无法完成推理。

1.2 联合类型与交叉类型

联合类型(Union Types)允许变量同时属于多个类型,用 | 符号分隔。例如:

let message: string | number = "Hello";  
message = 123; // 合法,因为 number 是联合类型的一部分  

交叉类型(Intersection Types)则通过 & 将多个类型合并为一个新类型,例如:

interface Person { name: string; }  
interface Employee { department: string; }  
type Manager = Person & Employee; // 合并后包含 name 和 department  

误区:联合类型在使用时需通过类型守卫(如 typeof)进行类型缩小,否则会引发“属性不存在”的错误。


二、函数与泛型

2.1 函数类型与参数约束

TypeScript 的函数需明确参数类型和返回值类型:

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

可选参数默认参数的结合使用需注意顺序:

function greet(name: string, greeting?: string): string {  
  return `${greeting || "Hello"} ${name}`;  
}  

2.2 泛型:类型参数的魔法

泛型通过 <T> 等占位符实现类型复用,避免重复代码。例如:

function identity<T>(arg: T): T {  
  return arg;  
}  
// 调用时指定类型:  
const result = identity<number>(42); // 显式指定类型  
const result2 = identity("TypeScript"); // 通过参数推断类型  

比喻:泛型如同“万能适配器”,它允许代码在运行时动态适配不同数据类型,而非硬编码特定类型。


三、接口与类

3.1 接口:定义对象的形状

接口(Interface)用于描述对象的结构:

interface User {  
  id: number;  
  username: string;  
  isActive?: boolean; // 可选属性  
}  

实现接口时,对象需满足所有必需属性:

const user: User = { id: 1, username: "alice" }; // 合法  
const invalidUser: User = { id: "1" }; // 错误,id 必须是 number  

3.2 类的静态类型与继承

类的静态属性和实例属性需分别定义:

class Calculator {  
  static PI: number = 3.14; // 静态属性  
  private result: number = 0; // 实例属性  
}  

继承时,子类需通过 extends 关键字并实现父类的所有抽象方法:

abstract class Animal {  
  abstract makeSound(): void; // 抽象方法  
}  
class Dog extends Animal {  
  makeSound() {  
    console.log("Woof!");  
  }  
}  

四、高级特性与工具链

4.1 类型断言与类型守卫

类型断言(Type Assertion)用于强制转换类型,但需谨慎使用:

const element = document.getElementById("myDiv") as HTMLDivElement;  

类型守卫(Type Guards)则通过条件逻辑确保类型安全,例如:

function printValue(x: string | number) {  
  if (typeof x === "string") {  
    console.log(x.toUpperCase()); // 此时 TypeScript 知道 x 是 string  
  } else {  
    console.log(x.toFixed(2)); // 此时 x 是 number  
  }  
}  

4.2 工具类型与实用工具

TypeScript 提供了丰富的工具类型,如 Partial<T>Readonly<T> 等,例如:

interface Todo {  
  title: string;  
  completed: boolean;  
}  
type PartialTodo = Partial<Todo>; // 所有属性变为可选  

工具链配置:通过 tsconfig.json 控制编译选项,例如:

{  
  "compilerOptions": {  
    "target": "ES6",  
    "module": "CommonJS",  
    "strict": true // 启用严格类型检查  
  }  
}  

五、常见陷阱与实战案例

5.1 类型兼容性陷阱

TypeScript 的类型兼容基于“结构兼容性”而非名称,这可能导致意外行为:

interface Point { x: number; y: number }  
class Coordinate implements Point {  
  x: number;  
  y: number;  
  z: number = 0; // 多余的属性不会影响兼容性  
}  

5.2 实战案例:类型安全的 API 客户端

假设我们需定义一个 API 响应接口:

interface ApiResponse<T> {  
  status: "success" | "error";  
  data?: T;  
  error?: string;  
}  
// 使用泛型处理不同数据类型  
function fetchData<T>(): Promise<ApiResponse<T>> {  
  return fetch("/api/data").then(response => response.json());  
}  

通过 TypeScript 的类型系统,我们能在编译时验证 API 响应的结构,避免运行时错误。


结论

通过本文的“TypeScript 测验”式学习,我们梳理了从基础类型到高级工具链的核心概念。TypeScript 不仅是 JavaScript 的超集,更是一种思维方式的转变——通过静态类型提前发现漏洞,用泛型提升代码复用性,最终构建更健壮的应用。对于开发者而言,掌握这些知识点如同“解锁代码的防御系统”,而实践是巩固知识的最佳方式。建议读者通过编写小型项目或参与开源贡献,将理论转化为实战能力。记住:TypeScript 的强大之处,不仅在于它的语法,更在于它对代码质量的长期保障。


(全文约 1600 字)

最新发布