A Reference Sheet for TypeScript Function, Class
A quick walkthrough of key concepts of TypeScript Function and Class
Note that some examples are extracted from the TypeScript Handbook, and all tributes should go to it.
Function
====> Function Expressionfunction greeter(fn: (a: string) => void) {
fn("Hello, World");
}function printToConsole(s: string) {
console.log(s);
}greeter(printToConsole);====> Type Aliastype GreetFunction = (a: string) => void;function greeter(fn: GreetFunction) {
// ...
}====> Call signature (for functions with additional properties) Note compared to a function type expression - use : between the parameter list and the return type rather than =>.type DescribableFunction = {
description: string; // additional properties
(a: string): void;
};function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn("hello"));
}====> Optional params
In JavaScript, if you call a function with more arguments than there are parameters, the extra arguments are simply ignored. TypeScript behaves the same way. Functions with fewer parameters can always take the place of functions with more parameters.====> Rest params
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x);
}
const a = multiply(10, 1, 2, 3, 4);====> Function overloadsSome JavaScript functions can be called in a variety of argument counts and types.In TypeScript, we can specify a function that can be called in different ways by writing overload signatures. To do this, write some number of function signatures (usually two or more), followed by the body of the function.In example below, these first two signatures are called the overload signatures.Then, we wrote a function implementation with a compatible signature.function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number)
: Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
CLASS
public:
the default visibility of class members is public
. Since it’s default, it can be ignored when writing.
class Greeter {
public greet() {
console.log("hi!");
}
}const g = new Greeter();
g.greet();
protected
: only visible to subclasses of the class they’re declared in.
class Greeter {
public greet() {
console.log("Hello, " + this.getName());
}
protected getName() {
return "hi";
}
}const g = new Greeter();
g.greet();
Exposure of protected
members
Derived classes need to follow their base class contracts, but may choose to expose a more general type with more capabilities. This includes making protected
members public
:
class Base {
protected m = 10;
}class Derived extends Base {
m = 15;
}const d = new Derived();
console.log(d.m);
Cross-hierarchy protected
access
TypeScript sides with C# and C++ in that accessing x
in DerivedClass
should only be legal from DerivedClass
’s subclasses:
class Base {
protected x: number = 1;
}class Derived1 extends Base {
protected x: number = 5;
}class Derived2 extends Base {
f1(other: Derived2) {
other.x = 10;
} f2(other: Base) {
other.x = 10;
//ERROR: Property 'x' is protected and only accessible through
//an instance of class 'Derived2'.
}
}
private
: restrict access to the member even from subclasses.
class Base {
private x = 0;
}class Derived extends Base {
showX() {
console.log(this.x);
//Property 'x' is private and only accessible
//within class 'Base'.
}
}
Cross-instance private
access
TypeScript does allow cross-instance private
access:
class A {
private x = 10;
public sameAs(other: A) {
return other.x === this.x;
}
}
Static members: can also use the same public
, protected
, and private
visibility modifiers:
class MyClass {
private static x = 0;
}
console.log(MyClass.x);
//Property 'x' is private and only accessible within class 'MyClass'.
Generic Classes
Classes, much like interfaces, can be generic. When a generic class is instantiated with new
, its type parameters are inferred the same way as in a function call:
class Box<Type> {
contents: Type;
constructor(value: Type) {
this.contents = value;
}
}const b = new Box("hello!");
That’s so much of it.
Happy Reading!