Classes-TypeScript官网Cheat Sheets

class

private 和 # 的区别

前缀 private 只是TS语法,在运行时不起作用,外部能够访问,但是类型检查器会报错
class Bag { private item: any }
修饰符 # 是JS语法,是运行时私有的,并且在JavaScript引擎内部强制执行,它只能在类内部访问
class Bag { #item: any }

类型和值(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

应用于类内部各种声明的装饰器,有一个明确定义的顺序:
  1. 实例成员,(参数装饰器,其次是方法),(访问器),(属性装饰器), 这三者按照声明顺序调用
  2. 静态成员,(参数装饰器,其次是方法),(访问器),(属性装饰器), 这三者按照声明顺序调用
  3. 构造函数参数修饰器
  4. 类修饰器
 还有一个注意点,参数修饰器中,越往后的参数修饰器,越早调用
复制代码
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

 

posted @   。吃什么  阅读(71)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示