文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载本文以开源项目 The Concise TypeScript Book 的韩语章节 website/src/content/docs/ko-kr/book/class.md对应英文原版 class.md为核心骨架系统讲解 TypeScript 中类的定义、构造、访问控制、继承、泛型、装饰器与重载等全部核心能力。读完本文你将掌握在 TypeScript 中编写类型安全、可复用、可扩展类结构的完整技能并了解该项目如何通过自动化工具校验文档中每一段 TypeScript 代码的真实可编译性。一、类Class的基础语法在 TypeScript 中class关键字用于定义一个类。下面是一个最基础的示例class Person { private name: string; private age: number; constructor(name: string, age: number) { this.name name; this.age age; } public sayHi(): void { console.log( Hello, my name is ${this.name} and I am ${this.age} years old. ); } }对这个示例逐行拆解class关键字定义了一个名为Person的类类中包含两个私有属性string类型的name和number类型的age构造函数使用constructor关键字定义接收name与age参数并赋值给对应属性类中有一个public方法sayHi用于打印问候信息。要在 TypeScript 中创建类的实例使用new关键字、后跟类名与括号()即可const myObject new Person(John Doe, 25); myObject.sayHi(); // Output: Hello, my name is John Doe and I am 25 years old.值得一提的是本项目对文档中的每一段 TypeScript 代码都会做真实编译校验。工具脚本 compile.ts 使用marked词法分析器提取 markdown 中的typescript代码块写入临时文件后通过ts.createProgram以strict: true、noImplicitAny: true、noEmitOnError: true编译并报告诊断信息带有!-- skip --注释的代码块如上面的实例化示例以及后文自动访问器的降级示例会被跳过编译。也就是说本文出现的绝大多数代码片段都是经该项目 CI 实际编译通过的真实代码。二、构造函数Constructor与构造函数重载构造函数是类中的特殊方法当类实例被创建时用于初始化对象属性class Person { public name: string; public age: number; constructor(name: string, age: number) { this.name name; this.age age; } sayHello() { console.log( Hello, my name is ${this.name} and Im ${this.age} years old. ); } } const john new Person(Simon, 17); john.sayHello();2.1 构造函数重载Constructor Overloading使用如下语法可以对构造函数进行重载type Sex m | f; class Person { name: string; age: number; sex: Sex; constructor(name: string, age: number, sex?: Sex); constructor(name: string, age: number, sex: Sex) { this.name name; this.age age; this.sex sex ?? m; } } const p1 new Person(Simon, 17); const p2 new Person(Alice, 22, f);TypeScript 允许定义多个构造函数重载签名但只能有一个与所有重载都兼容的实现这可以通过可选参数来实现class Person { name: string; age: number; constructor(); constructor(name: string); constructor(name: string, age: number); constructor(name?: string, age?: number) { this.name name ?? Unknown; this.age age ?? 0; } displayInfo() { console.log(Name: ${this.name}, Age: ${this.age}); } } const person1 new Person(); person1.displayInfo(); // Name: Unknown, Age: 0 const person2 new Person(John); person2.displayInfo(); // Name: John, Age: 0 const person3 new Person(Jane, 25); person3.displayInfo(); // Name: Jane, Age: 25注意多个重载签名在上、单个实现签名在下实现签名的参数必须是所有重载参数的「并集」通常通过可选参数name?: string与空值合并运算符??提供默认值来满足不同调用形态。2.2 私有与受保护构造函数Private and Protected ConstructorsTypeScript 可以将构造函数标记为private或protected从而限制其可访问性与使用方式。私有构造函数只能在类自身内部调用。常用于强制实现单例Singleton模式或把实例创建限制在类内部的工厂方法中。受保护构造函数适用于创建不应被直接实例化、但可被子类扩展的基类。class BaseClass { protected constructor() {} } class DerivedClass extends BaseClass { private value: number; constructor(value: number) { super(); this.value value; } } // Attempting to instantiate the base class directly will result in an error // const baseObj new BaseClass(); // Error: Constructor of class BaseClass is protected. // Create an instance of the derived class const derivedObj new DerivedClass(10);这里的关键点在于DerivedClass的构造函数中必须先调用super()因为基类构造函数虽然是protected但派生类仍然可以合法调用它来完成继承初始化。三、访问修饰符Access Modifiers访问修饰符private、protected、public用于控制类成员属性与方法的可见性和可访问性。它们是强制封装encapsulation、为访问和修改类内部状态划定边界的关键工具private将成员访问限制在包含它的类内部protected允许在包含它的类及其派生类内部访问public提供无限制访问可在任何位置访问默认访问级别。class Person { private name: string; protected age: number; public email: string; constructor(name: string, age: number, email: string) { this.name name; this.age age; this.email email; } }从本项目工具的编译配置看tsconfig.json 启用了strict: true文档中的所有访问修饰符示例都在严格模式下编译这意味着诸如「在类外访问private成员」这类错误会被编译器直接拦截保证了文档示例的规范性。四、getter 与 setterGet and Setgetter 和 setter 是特殊方法允许为类属性定义自定义的读取与修改行为。它们能把对象的内部状态封装起来并在取值或赋值时附加额外逻辑。TypeScript 中分别用get与set关键字定义class MyClass { private _myProperty: string; constructor(value: string) { this._myProperty value; } get myProperty(): string { return this._myProperty; } set myProperty(value: string) { this._myProperty value; } }实践中通常约定以_前缀命名私有字段如_myProperty再通过同名公开访问器暴露受控的读写接口便于在 setter 中执行校验、转换或通知等逻辑。五、类的自动访问器Auto-AccessorsTypeScript 4.9 起支持自动访问器auto-accessors这是一个即将纳入 ECMAScript 标准的新特性。它们看起来与类属性相似但使用accessor关键字声明class Animal { accessor name: string; constructor(name: string) { this.name name; } }自动访问器会被「降级de-sugar」为作用于一个不可访问属性的私有get/set访问器class Animal { #__name: string; get name() { return this.#__name; } set name(value: string) { this.#__name value; } constructor(name: string) { this.name name; } }可以看到accessor关键字本质上是一个语法糖编译期会自动生成基于私有字段#__name的 getter/setter 对既保留了字段的私有性又提供了与普通属性一致的使用体验。项目中该代码块带有!-- skip --标记因为降级后的#私有字段写法在部分目标环境下不适用故跳过编译校验机制见 compile.ts 中isSkipComment的实现。六、this关键字在 TypeScript 中this关键字在方法或构造函数内指向类的当前实例允许在类自身作用域内访问和修改类的属性与方法为在对象方法中读写对象内部状态提供了途径class Person { private name: string; constructor(name: string) { this.name name; } public introduce(): void { console.log(Hello, my name is ${this.name}.); } } const person1 new Person(Alice); person1.introduce(); // Hello, my name is Alice.需要留意的是this的绑定取决于方法被调用的方式将方法作为回调传递如setTimeout(person.introduce)时可能丢失正确的this指向需要结合箭头函数或bind处理不过文档正文未展开这一点在此仅作提示。七、参数属性Parameter Properties参数属性允许在构造函数参数中直接声明并初始化类属性从而避免样板代码。例如class Person { constructor( private name: string, public age: number ) { // The private and public keywords in the constructor // automatically declare and initialize the corresponding class properties. } public introduce(): void { console.log( Hello, my name is ${this.name} and I am ${this.age} years old. ); } } const person new Person(Alice, 25); person.introduce();构造函数参数前的private/public/protected/readonly等修饰符会自动声明并初始化同名类属性省去了「先声明字段、再在构造函数中逐行赋值」的重复劳动。这也是后文「静态成员」示例中constructor(private name: string)的写法依据。八、抽象类Abstract Classes抽象类在 TypeScript 中主要用于继承它提供了一种定义可被子类继承的公共属性与方法的方式。当你希望定义公共行为并强制子类实现某些方法时非常有用其核心价值在于构建「抽象基类提供共享接口与公共功能、子类负责具体实现」的类层级结构。abstract class Animal { protected name: string; constructor(name: string) { this.name name; } abstract makeSound(): void; } class Cat extends Animal { makeSound(): void { console.log(${this.name} meows.); } } const cat new Cat(Whiskers); cat.makeSound(); // Output: Whiskers meows.要点abstract关键字修饰的类不能被直接实例化abstract方法只有签名没有实现任何非抽象子类都必须实现它否则编译器会报错。本例中Cat必须提供makeSound的实现同时继承了基类的name属性protected仅子类可访问。九、与泛型结合使用Classes with Generics泛型类允许定义可针对不同类型工作的可复用类class ContainerT { private item: T; constructor(item: T) { this.item item; } getItem(): T { return this.item; } setItem(item: T): void { this.item item; } } const container1 new Containernumber(42); console.log(container1.getItem()); // 42 const container2 new Containerstring(Hello); container2.setItem(World); console.log(container2.getItem()); // World类型参数T在类实例化时被具体化Containernumber中getItem()返回numberContainerstring中则返回string类型安全贯穿整个容器生命周期避免了any带来的运行时类型隐患。十、装饰器Decorators装饰器提供了一种为目标元素添加元数据、修改行为、进行校验或扩展功能的机制。它们是在运行时执行的函数且一个声明上可以应用多个装饰器。10.1 兼容性与启用方式需要特别注意版本约束装饰器是实验性特性本文及书中的示例仅兼容 TypeScript 5 及以上版本配合 ES6对于5 之前的 TypeScript 版本需要在 tsconfig.json 中启用experimentalDecorators属性或在命令行中使用--experimentalDecorators但书中的示例在这种模式下不会工作注意TypeScript 5 的装饰器不允许装饰参数parameter。项目当前环境也印证了这一点网站工程 website/package.json 依赖typescript: ^5.9.3工具工程 tools/package.json 依赖typescript: ^5.4.5且 tools/tsconfig.json 的lib中包含了esnext.decorators说明整套文档与示例都是基于新版Stage 3装饰器语义编写的。装饰器的常见用途包括监听属性变化监听方法调用添加额外属性或方法运行时校验自动序列化与反序列化日志记录权限控制与认证错误防护。装饰器按目标可分为类装饰器、属性装饰器、方法装饰器、getter/setter 装饰器以及配套的装饰器元数据机制。10.2 类装饰器Class Decorators类装饰器适用于扩展已有类例如添加属性或方法、收集类实例等。下面这个例子为类添加了toString能力——实际上是通过返回一个包装类在构造时打印实例与上下文信息type ConstructorT {} new (...args: any[]) T; function toStringClass extends Constructor( Value: Class, context: ClassDecoratorContextClass ) { return class extends Value { constructor(...args: any[]) { super(...args); console.log(JSON.stringify(this)); console.log(JSON.stringify(context)); } }; } toString class Person { name: string; constructor(name: string) { this.name name; } greet() { return Hello, this.name; } } const person new Person(Simon); /* Logs: {name:Simon} {kind:class,name:Person} */注意新版装饰器函数的签名第一个参数是目标类装饰器为目标类构造函数第二个参数是上下文对象context其中kind和name描述了被装饰元素。10.3 属性装饰器Property Decorators属性装饰器用于修改属性行为例如改变初始化值。下面的代码让属性值在赋值时始终转为大写function upperCaseT( target: undefined, context: ClassFieldDecoratorContextT, string ) { return function (this: T, value: string) { return value.toUpperCase(); }; } class MyClass { upperCase prop1 hello!; } console.log(new MyClass().prop1); // Logs: HELLO!属性字段装饰器返回的替换函数会在字段初始化时被调用入参为初始值返回值成为最终存储值因此hello!被改写为HELLO!。10.4 方法装饰器Method Decorators方法装饰器允许改变或增强方法行为。下面是一个简单的日志器示例function logThis, Args extends any[], Return( target: (this: This, ...args: Args) Return, context: ClassMethodDecoratorContext This, (this: This, ...args: Args) Return ) { const methodName String(context.name); function replacementMethod(this: This, ...args: Args): Return { console.log(LOG: Entering method ${methodName}.); const result target.call(this, ...args); console.log(LOG: Exiting method ${methodName}.); return result; } return replacementMethod; } class MyClass { log sayHello() { console.log(Hello!); } } new MyClass().sayHello();运行输出如下LOG: Entering method sayHello. Hello! LOG: Exiting method sayHello.装饰器返回的replacementMethod包装了原方法通过target.call(this, ...args)保留正确的this上下文实现进入/退出的日志拦截。10.5 getter 与 setter 装饰器Getter and Setter Decorators访问器装饰器允许改变或增强类访问器的行为例如用于校验属性赋值。下面是一个 getter 装饰器示例校验取值必须在给定区间内function rangeThis, Return extends number(min: number, max: number) { return function ( target: (this: This) Return, context: ClassGetterDecoratorContextThis, Return ) { return function (this: This): Return { const value target.call(this); if (value min || value max) { throw Invalid; } Object.defineProperty(this, context.name, { value, enumerable: true, }); return value; }; }; } class MyClass { private _value 0; constructor(value: number) { this._value value; } range(1, 100) get getValue(): number { return this._value; } } const obj new MyClass(10); console.log(obj.getValue); // Valid: 10 const obj2 new MyClass(999); console.log(obj2.getValue); // Throw: Invalid!range(1, 100)是一个装饰器工厂——它先接收参数返回真正的装饰器装饰器再包装 getter在取值时校验范围越界即抛出Invalid。10.6 装饰器元数据Decorator Metadata装饰器元数据简化了装饰器在任意类中应用与利用元数据的过程。装饰器可以访问上下文对象上新增的metadata属性该属性可作为原始值与对象的键元数据信息可通过Symbol.metadata在类上获取。元数据可用于调试、序列化或基于装饰器的依赖注入等场景。//ts-ignore Symbol.metadata ?? Symbol(Symbol.metadata); // Simple polyfill type Context | ClassFieldDecoratorContext | ClassAccessorDecoratorContext | ClassMethodDecoratorContext; // Context contains property metadata: DecoratorMetadata function setMetadata(_target: any, context: Context) { // Set the metadata object with a primitive value context.metadata[context.name] true; } class MyClass { setMetadata a 123; setMetadata accessor b b; setMetadata fn() {} } const metadata MyClass[Symbol.metadata]; // Get metadata information console.log(JSON.stringify(metadata)); // {bar:true,baz:true,foo:true}该示例展示了同一个setMetadata装饰器可以同时作用于字段a、自动访问器accessor b与方法fn每个被装饰成员的名字都会作为键写入共享的metadata对象最终通过MyClass[Symbol.metadata]统一读取。示例开头的Symbol.metadata ?? ...是一个简易 polyfill用于在尚未原生支持该符号的环境中兜底代码块前的//ts-ignore用于抑制严格模式下的类型告警。十一、继承Inheritance继承指一个类可以从另一个类基类或超类继承属性与方法。派生类也叫子类可以通过添加新属性、新方法或重写已有成员来扩展和特化基类功能class Animal { name: string; constructor(name: string) { this.name name; } speak(): void { console.log(The animal makes a sound); } } class Dog extends Animal { breed: string; constructor(name: string, breed: string) { super(name); this.breed breed; } speak(): void { console.log(Woof! Woof!); } } // Create an instance of the base class const animal new Animal(Generic Animal); animal.speak(); // The animal makes a sound // Create an instance of the derived class const dog new Dog(Max, Labrador); dog.speak(); // Woof! Woof!要点派生类构造函数必须先调用super(...)完成基类初始化才能访问thisDog.speak()重写了基类的speak()实现了方法覆盖override。11.1 单继承与多接口实现TypeScript不支持传统意义上的多重继承一个类只能继承自一个基类但 TypeScript 支持多个接口——接口可以定义对象结构的契约一个类可以implements多个接口从而从多个来源继承行为与结构interface Flyable { fly(): void; } interface Swimmable { swim(): void; } class FlyingFish implements Flyable, Swimmable { fly() { console.log(Flying...); } swim() { console.log(Swimming...); } } const flyingFish new FlyingFish(); flyingFish.fly(); flyingFish.swim();11.2 class 的本质语法糖与 JavaScript 一样TypeScript 中的class关键字常被称为语法糖。它在 ECMAScript 2015ES6中引入为以类的方式创建和操作对象提供了更熟悉的语法。但必须注意TypeScript 是 JavaScript 的超集最终会被编译为 JavaScript而 JavaScript 的核心依然是**基于原型prototype-based**的——类本质上仍是构造函数与原型链的封装。十二、静态成员StaticsTypeScript 支持静态成员。访问类的静态成员时无需创建对象直接用「类名.成员名」即可class OfficeWorker { static memberCount: number 0; constructor(private name: string) { OfficeWorker.memberCount; } } const w1 new OfficeWorker(James); const w2 new OfficeWorker(Simon); const total OfficeWorker.memberCount; console.log(total); // 2static memberCount属于类本身而非实例每创建一个OfficeWorker实例构造函数就使memberCount自增一次最终通过OfficeWorker.memberCount读出总人数 2。静态成员适合存放与类相关的全局计数、配置常量或工具方法。十三、属性初始化Property InitializationTypeScript 中初始化类属性有几种方式。内联Inline初始化——实例创建时使用这些初始值class MyClass { property1: string default value; property2: number 42; }在构造函数中初始化class MyClass { property1: string; property2: number; constructor() { this.property1 default value; this.property2 42; } }使用构造函数参数参数属性 默认值class MyClass { constructor( private property1: string default value, public property2: number 42 ) { // There is no need to assign the values to the properties explicitly. } log() { console.log(this.property2); } } const x new MyClass(); x.log();第三种方式把「声明、初始化、默认值」三件事合并到构造参数中private property1: string default value既声明了属性又设定了默认值无需在构造体内显式赋值。需要说明的是在strict模式下本项目 tsconfig.json 与 compile.ts 均启用strict类属性若未初始化且无默认值会触发「属性没有初始化器」的告警因此文档中列出的三种方式也是消除该类告警的标准做法。十四、方法重载Method Overloading方法重载允许一个类拥有同名但参数类型或参数数量不同的多个方法从而根据传入参数以不同方式调用同一方法class MyClass { add(a: number, b: number): number; // Overload signature 1 add(a: string, b: string): string; // Overload signature 2 add(a: number | string, b: number | string): number | string { if (typeof a number typeof b number) { return a b; } if (typeof a string typeof b string) { return a.concat(b); } throw new Error(Invalid arguments); } } const r new MyClass(); console.log(r.add(10, 5)); // Logs 15与构造函数重载类似先声明两个重载签名(number, number): number与(string, string): string再提供兼容所有签名的实现签名参数类型取联合类型number | string。实现内部通过typeof类型守卫区分数字相加与字符串拼接参数组合不合法时抛出异常。重载让调用方获得精确的返回类型推断——r.add(10, 5)的类型是number而非number | string。结语本文围绕 The Concise TypeScript Book 的 Class 章节完整覆盖了 TypeScript 类的 14 个核心主题基础语法、构造函数及其重载、私有/受保护构造函数、访问修饰符、getter/setter、自动访问器、this、参数属性、抽象类、泛型类、六类装饰器及其元数据机制、继承与多接口实现、静态成员、属性初始化和方法重载。文中所有代码均可直接复制运行且大部分经过项目工具链compile.ts、verify_codeblocks.py、tsconfig.json在strict模式下的真实编译校验。若需继续深入可参考同仓库的其他章节文档例如 访问修饰符与接口、泛型 与 类型操作按主题循序渐进地构建完整的 TypeScript 知识体系。赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐如何配置 CesiumJS 在完全离线环境中运行本地影像与 3D Tiles 数据如何配置 CesiumJS 在完全离线环境中运行本地影像与 3D Tiles 数据 默认情况下CesiumJS 在运行时会使用多个需要联网的外部数据源 V文档教程TypeScript 类完全指南从基础语法到装饰器The Concise TypeScript Book 实战解读TypeScript 类完全指南从基础语法到装饰器The Concise TypeScript Book 实战解读 导读 本文以开源项目 The Conc文档教程TypeScript 类Class深度指南从基础语法到装饰器实战 —— 基于 The Concise TypeScript BookTypeScript 类Class深度指南从基础语法到装饰器实战 —— 基于 The Concise TypeScript Book 本指南以 The C文档教程上一篇【亲测免费】 LD2410 项目使用教程下一篇如何使用App Privacy Policy Generator5分钟生成合规的应用隐私政策创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考