Class Values
Classes and builtin constructors are values: stored, passed, picked at run time, and constructed with `new` through any expression.
class Shape {
static count = 0;
name = "shape";
size: number;
constructor(size = 0) {
this.size = size;
Shape.count++;
}
area(): number {
return 0;
}
static unit(): Shape {
const s = new Shape(1);
s.name = "unit";
return s;
}
}
class Square extends Shape {
constructor(side: number) {
super(side);
this.name = "square";
}
area(): number {
return this.size * this.size;
}
}
// A class through a `typeof` binding, a parameter and an array.
let Kind: typeof Shape = Square;
console.log(new Kind(3).area(), Kind.name, Kind.unit().name);
function build(C: typeof Shape, n: number): Shape {
return new C(n);
}
console.log(build(Shape, 1).name, build(Square, 4).area());
const kinds: (typeof Shape)[] = [Shape, Square];
for (const k of kinds) console.log(k.name, new k(2).area());
// A constructor-typed parameter infers the instance type.
function make<T>(ctor: new () => T): T {
return new ctor();
}
console.log(make(Shape).name, make(Map).size);
// `new` through a member, an index and a call.
class Factory {
Product: typeof Shape = Square;
create(): Shape {
return new this.Product(5);
}
}
console.log(new Factory().create().area());
const registry = { Shape, Square };
console.log(new registry.Square(6).area());
const pick = (big: boolean) => (big ? Square : Shape);
console.log(new (pick(true))(7).area());
// Builtin constructors as values.
const M = Map;
const m = new M<string, number>([["Thessaloniki", 1]]);
console.log(m.get("Thessaloniki"), M.name);
const ctors: any[] = [Set, Date, Error];
console.log(new ctors[0]([1, 2, 2]).size, new ctors[1](0).getTime(), new ctors[2]("boom").message);
// Statics through the class value.
Kind.count = 100;
console.log(Shape.count);
try {
const notACtor: any = 5;
new notACtor();
} catch (e) {
console.log((e as Error).message);
}View source on GitHubexamples/classes/class_values.ts