TypeScript 类全面解析:从基础到高级特性

TypeScript 类全面解析:从基础到高级特性

TypeScript TypeScript 使用手册(中文版)翻译。http://www.typescriptlang.org TypeScript 项目地址: https://gitcode.com/gh_mirrors/typ/TypeScript

前言

TypeScript 作为 JavaScript 的超集,对 ES2015 引入的类(class)概念提供了全面支持,并在此基础上增加了类型系统和更多面向对象特性。本文将深入探讨 TypeScript 中类的各种特性和用法,帮助开发者更好地理解和使用这一重要概念。

类的基本结构

最简单的类定义

class Point {}

这个空类虽然现在没什么用,但它展示了类定义的最基本形式。在 TypeScript 中,类可以包含字段、构造函数、方法等多种成员。

类字段

类字段定义了类的实例属性:

class Point {
  x: number;
  y: number;
}

字段可以有类型注解,也可以有初始化器。当使用初始化器时,TypeScript 会自动推断字段类型:

class Point {
  x = 0;  // 推断为 number 类型
  y = 0;
}
严格属性初始化

TypeScript 提供了 strictPropertyInitialization 选项,用于控制是否需要在构造函数中初始化类字段:

class BadGreeter {
  name: string;  // 错误:属性 'name' 没有初始化
}

class GoodGreeter {
  name: string;
  
  constructor() {
    this.name = "hello";
  }
}

如果确实需要通过其他方式初始化字段,可以使用明确赋值断言操作符 !

class OKGreeter {
  name!: string;  // 告诉 TypeScript 我们知道这个字段会被初始化
}

构造函数

类的构造函数与普通函数类似,可以带有参数、默认值和重载:

class Point {
  x: number;
  y: number;
  
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
}

在继承体系中,派生类必须在访问 this 前调用 super()

class Base {
  k = 4;
}

class Derived extends Base {
  constructor() {
    super();  // 必须先调用 super()
    console.log(this.k);
  }
}

访问控制修饰符

TypeScript 提供了三种访问控制修饰符来控制类成员的可见性:

public

public 是默认修饰符,表示成员在任何地方都可以访问:

class Greeter {
  public greet() {
    console.log("hi!");
  }
}

protected

protected 成员只能在类及其子类中访问:

class Greeter {
  protected getName() {
    return "hi";
  }
}

class SpecialGreeter extends Greeter {
  public howdy() {
    console.log(this.getName());  // 可以访问
  }
}

private

private 成员只能在类内部访问,子类也无法访问:

class Base {
  private x = 0;
}

class Derived extends Base {
  showX() {
    console.log(this.x);  // 错误:无法访问私有成员
  }
}

需要注意的是,TypeScript 的 privateprotected 只在编译时进行类型检查,运行时仍然可以访问。如果需要真正的运行时私有性,可以使用 JavaScript 的私有字段语法 #

class Dog {
  #barkAmount = 0;  // 真正的私有字段
}

静态成员

静态成员属于类本身而不是实例:

class MyClass {
  static x = 0;
  static printX() {
    console.log(MyClass.x);
  }
}

静态成员也可以有访问修饰符:

class MyClass {
  private static x = 0;
}

继承与接口实现

继承

使用 extends 关键字实现继承:

class Animal {
  move() {
    console.log("Moving!");
  }
}

class Dog extends Animal {
  woof(times: number) {
    for (let i = 0; i < times; i++) {
      console.log("woof!");
    }
  }
}

接口实现

使用 implements 关键字实现接口:

interface Pingable {
  ping(): void;
}

class Sonar implements Pingable {
  ping() {
    console.log("ping!");
  }
}

高级特性

索引签名

类可以定义索引签名,用于处理动态属性:

class MyClass {
  [s: string]: boolean | ((s: string) => boolean);
  
  check(s: string) {
    return this[s] as boolean;
  }
}

泛型类

类可以是泛型的,类似于泛型接口:

class Box<T> {
  contents: T;
  constructor(value: T) {
    this.contents = value;
  }
}

const stringBox = new Box("hello");

this 绑定问题与解决方案

JavaScript 的 this 绑定有时会带来意外行为:

class MyClass {
  name = "MyClass";
  getName() {
    return this.name;
  }
}

const obj = {
  name: "obj",
  getName: new MyClass().getName
};

console.log(obj.getName());  // 输出 "obj" 而不是 "MyClass"

解决方案之一是使用箭头函数:

class MyClass {
  name = "MyClass";
  getName = () => {
    return this.name;
  };
}

总结

TypeScript 的类系统在 JavaScript 类的基础上增加了类型安全和更多面向对象特性。通过合理使用访问控制修饰符、继承、接口实现等特性,可以构建出更加健壮和可维护的代码结构。理解这些特性的工作原理和适用场景,对于编写高质量的 TypeScript 代码至关重要。

TypeScript TypeScript 使用手册(中文版)翻译。http://www.typescriptlang.org TypeScript 项目地址: https://gitcode.com/gh_mirrors/typ/TypeScript

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郝隽君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值