TypeScript Generics

Generics

1
2
3
4
5
6
7
8
function foo<T>(arg: T): T {
return arg
}

function len<T>(arg: Array<T>): Array<T> {
console.log(arg.length)
return arg
}

Generics Types

1
2
3
4
5
6
7
8
9
10
11
function foo<T>(arg: T): T {
return arg
}

interface fooInterface<T> {
(arg: T): T
}

let myFunction: <T>(arg: T) => T = foo
let otherFunction: { <T>(arg: T): T } = foo
let interfaceFunction: fooInterface<number> = foo

Generics Classes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class GenericsNumber<T> {
zeroValue: T
add: (x: T, y: T) => T
}

let number = new GenericsNumber<number>()
number.zeroValue = 0
number.add = function (x, y) {
return x + y
}

let string = new GenericsNumber<string>()
string.zeroValue = ""
string.add = function (x, y) {
return x + y
}

console.log(string.add(string.zeroValue, "test"))

Generics Constraints

1
2
3
4
5
6
7
8
interface Lengthwise {
length: number
}

function foo<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg
}

Using Type Parameters in Generic Constraints

1
2
3
4
5
6
7
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}

let obj = { a: 1, b: 2, c: 3, d: 4 }
console.log(getProperty(obj, "a"))
console.log(getProperty(obj, "e")) // error

Using Class Types in Generics

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function create<T>(c: { new (): T }): T {
return new c()
}

class BeeKeeper {
constructor(private hasMask: boolean = false) {}
}

class ZooKeeper {
constructor(private nameTag: string = "undefined") {}
}

class Animal {
constructor(private numLegs: number = 0) {}
}

class Bee extends Animal {
constructor(num: number, public keeper: BeeKeeper) {
super(num)
}
}

class Lion extends Animal {
constructor(num: number, public keeper: ZooKeeper) {
super(num)
}
}

function createInstance<A extends Animal>(
c: new (x, y) => A,
numLegs: number,
keeper: any
): A {
return new c(numLegs, keeper)
}

console.log(createInstance(Bee, 2, new BeeKeeper(true)))
console.log(createInstance(Lion, 4, new ZooKeeper("lion")))