Like Java
constructor(public publicProperty: type)
- shorthand to declare both parameter and property(ECMAScript 5+)
Accessors are automatically 'readonly'
class T{}:
What 'new' actually do:
'typeof' T (where T is a class):
class T {
static staticP = 'p'
tellStaticP() {
console.log(T.staticP)
}
}
// T is in fact a constructor function
console.log(typeof T) // function
// 'typeof' used as value returns a string
console.log(typeof(typeof T)) // string
console.log(typeof T === 'function') // true
// what is an instance of T?
let instanceOfT : T
instanceOfT = new T()
console.log(typeof instanceOfT) // object
console.log(instanceOfT instanceof T) // true
console.log(Object.getPrototypeOf(instanceOfT)) // T{}
console.log(Object.getPrototypeOf(instanceOfT) === T.prototype) // true
console.log(Object.getPrototypeOf(instanceOfT).constructor === T) // true
console.log(Object.getPrototypeOf(instanceOfT).constructor.staticP === T.staticP) // true
console.log(Object.getPrototypeOf(instanceOfT).tellStaticP === instanceOfT.tellStaticP) // true
// let t2: T = T // Compile error: Property 'tellStaticP' is missing in type 'typeof T' but required in type 'T'
// the line above does not work, because 'T' as type means an instance of T, therefore assigning T, the constructor function,
// is an error because the instance of T requires a member function 'tellStaticP' at least in its prototypes
// SUMMARY: 'T' as a type specifies instance of T, with requirements (such as 'tellStaticP') to make a value assignable to 'T'
// SUMMARY: an instance is an object, which's prototype is the 'prototype' property of a function
// SUMMARY: the prototype has a 'constructor' property pointing to the constructor function
// SUMMARY: static member of class is attached to the class (the constructor function)
// SUMMARY: non-static (instance) method is attached to the prototype
console.log("===================================================")
// what is 'typeof T'?
let anotherNameOfSameT: typeof T // here 'typeof' being used as a type, not a value
anotherNameOfSameT = T
console.log(typeof anotherNameOfSameT) // function
console.log(anotherNameOfSameT instanceof T) // false
console.log(Object.getPrototypeOf(anotherNameOfSameT)) // [Function]
console.log(Object.getPrototypeOf(anotherNameOfSameT) === Function.prototype) // true
console.log(anotherNameOfSameT === T) // true
anotherNameOfSameT.staticP = 'new P'
let instanceOfNewT : T = new anotherNameOfSameT()
instanceOfT.tellStaticP() // new P
instanceOfNewT.tellStaticP() // new P
// SUMMARY: typeof T used as a type means the 'constructor function as a type'
// SUMMARY: since a class in typescript is just a constructor function, it can be changed in runtime
console.log("===================================================")
let anotherClassOfT: typeof T
anotherClassOfT = class {
static staticP = 'another P'
tellStaticP() {
console.log("telling from anotherClassOfT, T.staticP: ", T.staticP) // new P
console.log("telling from anotherClassOfT, my own staticP: ", Object.getPrototypeOf(this).constructor.staticP) // another P
}
}
let instanceOfAnotherClassOfT : T = new anotherClassOfT()
instanceOfAnotherClassOfT.tellStaticP()
// SUMMARY: 'typeof T' as a type, is not exactly T (T is T), but type of constructor functions with those type checks
// SUMMARY: here another class can be assigned to a variable of 'typeof T', as long as the class satisfies those checks (required members)
// SUMMARY: so 'typeof T' as a type, is required 'public side signature' of constructor functions
// T = anotherClassOfT // this does not work, T is not a variable
/*
FINAL SUMMARY:
class T{} // T is a constructor function
let typeofT = typeof T // typeof T used as value, is a string, 'function'
let someClass : typeof T // typeof T used as type, is the 'public face' of T,
// so long other constructor function satisfies to this 'public face', it's assignable
*/
First needs to understand the constructor function (see above)
Then since class name used as a type specifies the instance type, it can be used as an interface.
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
class Clock implements ClockInterface {... // implement an interface
// extends
class Dog extends Animal {...
constructor(.....){
.......
super(.....)
// abstract
abstract class Animal {
abstract makeSound(): void;