TypeScript Interface

Interface

1
2
3
4
5
6
7
8
9
10
interface labelValue {
label: string
}

function printLabel(obj: labelValue): void {
console.log(obj.label)
}

let obj = { size: 10, label: "some text" }
printLabel(obj)

Optional Properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface SquareConfig {
color?: string
width?: number
}

function createSquare(config: SquareConfig): { color: string; area: number } {
let defaultSquare = { color: "White", area: 200 }
if (config.color) defaultSquare.color = config.color
if (config.width) defaultSquare.area = config.width ** 2

return defaultSquare
}

console.log(createSquare({ color: "Black", width: 30 }))

Readonly Properties

1
2
3
4
5
6
7
interface Point {
readonly x: number
readonly y: number
}

let readOnlyArray: ReadonlyArray<number> = [1, 2, 3, 4]
let a: number[] = readOnlyArray as number[] // readonly array assignment to ordinary array

Excess Property Checks

1
2
3
4
5
6
7
interface SquareConfig {
color?: string
width?: number
[propName: string]: any
}

let newSquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig)

Function Types

1
2
3
4
5
6
7
interface foo {
(source: string, subString: string): boolean
}

let mySearchFunction: foo = function (src, sub) {
return src.search(sub) > -1
}

Indexable Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface StringArray {
[index: number]: string
}

let myArray: StringArray = ["text1", "text2"]
let text1 = myArray[0]

interface NumberDictionary {
[index: string]: number

length: number
name: string // error
}

interface ReadonlyStringArray {
readonly [index: number]: string
}

let readonly: ReadonlyStringArray = ["text1", "text2"]
readonly[2] = "change" // error

Class Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface ClockInterface {
currentTime: Date

setTime(d: Date)
}

class Clock implements ClockInterface {
constructor(h: number, m: number) {}

currentTime: Date

setTime(d: Date) {
this.currentTime = d
}
}

Static sides of class

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
interface ClockInterface {
tick()
}

interface ClockConstructor {
new (hour: number, minute: number): ClockInterface
}

function createClock(
ctor: ClockConstructor,
hour: number,
minute: number
): ClockInterface {
return new ctor(hour, minute)
}

class DigitalClock implements ClockInterface {
constructor(h: number, m: number) {}

tick() {
console.log("tick")
}
}

class AnalogClock implements ClockInterface {
constructor(h: number, m: number) {}

tick() {
console.log("tick22222")
}
}

let digital = createClock(DigitalClock, 12, 0)
let analog = createClock(AnalogClock, 12, 1)

Extending Interfaces

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface A {
color: string
}

interface B {
width: number
}

interface Square extends A, B {
sideLength: number
}

let square = {} as Square
square.color = "white"
square.width = 2
square.sideLength = 4

Hybrid Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Counter {
(start: number): string

interval: number

reset(): void
}

function getCounter(): Counter {
let counter = function (start: number) {
// some thing
} as Counter
counter.interval = 20
counter.reset = function () {
// some thing
}
return counter
}

let counter = getCounter()
counter(10)
counter.reset()
counter.interval = 10

Interface Extending Classes

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
class Control {
private state: any
}

interface SelectableControl extends Control {
select(): void
}

class Button extends Control implements SelectableControl {
// subclass of Control & implement the interface
select(): void {
// from the interface
// some thing
}
}

class TextBox extends Control {
// subclass of Control
select(): void {
// custom function
// some thing
}
}

class Image implements SelectableControl {
// just implement the interface, but not the subclass of Control
private state: any // need to add.

select(): void {
// some thing
}
}