Classes-TypeScript官网Cheat Sheets
class
private 和 # 的区别
前缀 private 只是TS语法,在运行时不起作用,外部能够访问,但是类型检查器会报错
class Bag { private item: any }
修饰符 # 是JS语法,是运行时私有的,并且在JavaScript引擎内部强制执行,它只能在类内部访问
class Bag { #item: any }
修饰符 #,MDN 参考链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Private_class_fields#%E8%AF%AD%E6%B3%95
类型和值(Type and Value)
class 能够作为一个类型和一个值,但是最好不要这么做
class Bag { } const a: Bag = new Bag() class C implements Bag { }
常用语法(common Syntax)
class User { name: string // 必须声明才能在 constructor 赋值 constructor(name: string) { this.name = name } }
以下是上面简写,public 可换成 private ,public readonly,protected, 等等......,但不能是 js 语法 static 和 # 修饰符
class User {
constructor(public name:string){}
}
其它常用语法
interface Updatable { } type Serializzable = {} class Account { } // 继承 Account 类,实现 Updatable 接口 和 Serializzable 类型 class User extends Account implements Updatable, Serializzable { id: string; displayName?: boolean; // 可选 name!: string; // 告诉类型检查器 name 有值 #attributes: Map<any, any>; // 私有属性,js语法 roles = ["user"]; // 默认值 readonly createdAt = new Date(); //只读属性 constructor(id: string) { super() this.id = id this.#attributes = new Map() } setName(name: string) { this.name = name } // 原型方法 verifyName = (name: string) => { this.name = name } // 实例方法 // 函数重载 sync(): Promise<{}> sync(cb: (result: string)=>void): void // 方法类型声明完成,后要接着方法实现 sync(cb?: (result: string)=>void): void | Promise<{}>{} // Getters and Setters get accountID(){return 123} set accountID(value: number){ /** ... */ } // protected 只能在类和继承类的后代类中使用,不可以在实例中使用 protected handleReques(){} // 静态类型,js语法 static #userCount = 0 // 只能在静态方法里使用 static registerUser(user: number){this.#userCount = user} }
泛型(Generics)
class Box<Type>{ constructor(public content:Type){} } const stringBox = new Box("a package") // stringBox: Box<string>
抽象类(Abstract Classes)
在 TypeScript 中,类,方法和字段都可以是抽象的。抽象方法和字段都只能出现在抽象类中。
抽象类自身不能实例化,只能作为派生类的基类,派生类必须实现抽象类的所有抽象方法和字段。
abstract class Base { abstract getName(): string; printName() { console.log("Hello, " + this.getName()); } } const b = new Base(); // 错误,无法创建抽象类的实例。 class Derived extends Base { // 必须实现该抽象函数 getName() { return "world"; } } const d = new Derived(); d.printName();
抽象构造签名(Abstract Construct Signatures)
有时你想接受一个构造函数,产生一个实例,这个构造函数是某个抽象类派生的类。
Bad!这种写法,在传递抽象类的时候 TypeScript 没有报错,只有new 实例化才报错
function greet(ctor: typeof Base) { const instance = new ctor(); // 无法创建抽象类的实例。 instance.printName(); } greet(Base);
Great!接受一个带有构造签名的参数,这种写法,在传递抽象类的时候 TypeScript 就报错了
function greet2(ctor: new () => Base) { const instance = new ctor(); instance.printName(); } greet2(Derived); greet2(Base);
抽象类继承抽象类
抽象类继承抽象类,两抽象类会进行合并,出现相同名称的抽象方法和字段,如果不同类型会报错,但是相同类型,子类型,any,这些都不会报错。
abstract class Base { abstract getName(): string; abstract asd: string printName() { console.log("Hello, " + this.getName()); } } abstract class Bag extends Base { abstract getName(): any; // 相同抽象方法,返回值改为any,不报错 abstract asd: '456' // 相同抽象字段,返回值改为 string 子类型,不报错 } class Derived extends Bag { constructor(public asd: '456') { super() } getName() { return 123; } } const d = new Derived('456'); d.printName();
这里的 extends 是js 语法,类只能继承一个。并不是 ts 的 extends, 用于 Interface 扩展,和类型缩窄
class Derived extends Bag, Base {} // 错误
修饰器和属性(Decorators and Attributes)
在 "tsconfig" 中打开 "experimentalDecorators"
可以在类,方法,方法参数,属性和访问器上用修饰器
import { Syncable, triggerSync, preferCache, required } from "mylib" @Syncable class User { @triggerSync() // 方法 save() { } @preferCache(false) // 访问器 get displayName() { } update(@required info: Partial<User>) { } // 方法参数 }
一个声明应用多个装饰器,会从下到上调用
function first(target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log("first(): called"); }; function second(target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log("second(): called"); }; class ExampleClass { // 单行,多行,两种写法 @first @second method() { } // @first // @second // method() { } } const exampleClass = new ExampleClass(); exampleClass.method() // second(): called // first(): called
一个声明应用多个装饰器工厂(decorator factories),会从上到下调用后,再从下到上调用返回的函数
function first() { console.log("first(): factory evaluated"); return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log("first(): called"); }; } function second() { console.log("second(): factory evaluated"); return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log("second(): called"); }; } class ExampleClass { @first() @second() method() { } } const exampleClass = new ExampleClass(); exampleClass.method() // first(): factory evaluated // second(): factory evaluated // second(): called // first(): called
Decorator Evaluation
应用于类内部各种声明的装饰器,有一个明确定义的顺序:
- 实例成员,(参数装饰器,其次是方法),(访问器),(属性装饰器), 这三者按照声明顺序调用
- 静态成员,(参数装饰器,其次是方法),(访问器),(属性装饰器), 这三者按照声明顺序调用
- 构造函数参数修饰器
- 类修饰器
还有一个注意点,参数修饰器中,越往后的参数修饰器,越早调用
function classDecorator(constructor: Function) { console.log("classDecorator"); }; function propertyDecorator(name: string) { return function (target: any, propertyKey: string) { console.log(name); } } function parameterDecorator(name: string) { return function (target: any, functionName: string, index: number) { console.log(name); } } function methodDecorator(name: string) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log(name); }; } function accessorDecorator(name: string) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log(name); } } @classDecorator class ExampleClass { constructor(@parameterDecorator("constructorParameter") greeting: string, @parameterDecorator("constructorParameter2") public appService: string) { this.greeting = greeting } @accessorDecorator("staticAccessor") static get x() {return 123} @propertyDecorator("staticProperty") static id: number @methodDecorator("staticMethod") static smethod(@parameterDecorator('staticParmeter') value: string) { } @propertyDecorator("instanceProperty") greeting: string @methodDecorator("instanceMethod") method(value: string, @parameterDecorator('instanceParmeter') value2: string) { } @accessorDecorator("instanceAccessor") get x() {return 123} } const exampleClass = new ExampleClass('asd', 'wew'); exampleClass.method('a', 'b') // [LOG]: "instanceProperty" // [LOG]: "instanceParmeter" // [LOG]: "instanceMethod" // [LOG]: "instanceAccessor" // [LOG]: "staticAccessor" // [LOG]: "staticProperty" // [LOG]: "staticParmeter" // [LOG]: "staticMethod" // [LOG]: "constructorParameter2" // [LOG]: "constructorParameter" // [LOG]: "classDecorator"
感谢观看,欢迎互相讨论与指导,以下是参考资料链接🔗
https://www.typescriptlang.org/static/TypeScript%20Classes-83cc6f8e42ba2002d5e2c04221fa78f9.png
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)