时光的涂鸦墙

code is poetry

typescript

基础类型

为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。

boolean

1
let isDone: boolean = false

number

1
2
3
4
let decLiteral: number = 6
let hexLiteral: number = 0xf00d
let binaryLiteral: number = 0b1010
let octalLiteral: number = 0o744

string

1
2
let name: string = 'bob'
name = 'smith'

当然也可以用模板字符串:

1
2
3
4
let name: string = `Gene`
let age: number = 37
let sentence: string = `Hello, my name is ${name}.I'll be ${age +
1} years old next month.`

array

  • 在元素类型后面接上 [],表示由此类型元素组成的一个数组:

    1
    let list: number[] = [1, 2, 3]
  • 使用数组泛型,Array<元素类型>:

    1
    let list: Array<number> = [1, 2, 3]

元组 Tuple

元组类型允许表示一个已知元素数量类型的数组,各元素的类型不必相同。

1
2
3
4
5
6
// Declare a tuple type
let x: [string, number]
// Initialize it
x = ['hello', 10] // OK
// Initialize it incorrectly
x = [10, 'hello'] // Error

打印出来的结果:

1
2
console.log(x[0].substr(1)) // OK
console.log(x[1].substr(1)) // Error, 'number' does not have 'substr'

枚举

像 C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。

1
2
enum Color {Red, Green, Blue};
let c: Color = Color.Green;

默认情况下,从 0 开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1 开始编号:

1
2
enum Color {Red = 1, Green, Blue};
let c: Color = Color.Green;

或者全部手动赋值:

1
2
enum Color {Red = 1, Green = 2, Blue = 4};
let c: Color = Color.Green;

枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为 2,但是不确定它映射到 Color 里的哪个名字,我们可以查找相应的名字:

1
2
3
4
enum Color {Red = 1, Green, Blue};
let colorName: string = Color[2];

alert(colorName);

任意值

1
2
3
let notSure: any = 4
notSure = 'maybe a string instead'
notSure = false // okay, definitely a boolean

空值

某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:

1
2
3
function warnUser(): void {
alert('This is my warning message')
}

Null 和 Undefined

1
2
3
// Not much else we can assign to these variables!
let u: undefined = undefined
let n: null = null

类型断言

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。

  • “尖括号”语法:

    1
    2
    let someValue: any = "this is a string";
    let strLength: number = (<string>someValue).length;
  • as 语法

    1
    2
    let someValue: any = "this is a string";
    let strLength: number = (someValue as string).length;

变量声明

var 声明

1
2
3
4
5
6
7
8
9
10
function f() {
var a = 10
return function g() {
var b = a + 1
return b
}
}

var g = f()
g() // returns 11;

let 声明

const 声明

const 拥有与 let 相同的作用域规则,但是不能对它们重新赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const numLivesForCat = 9
const kitty = {
name: 'Aurora',
numLives: numLivesForCat
}

// Error
kitty = {
name: 'Danielle',
numLives: numLivesForCat
}

// all "okay"
kitty.name = 'Rory'
kitty.name = 'Kitty'
kitty.name = 'Cat'
kitty.numLives--

let vs. const

使用最小特权原则,所有变量除了你计划去修改的都应该使用 const。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用 const 也可以让我们更容易的推测数据的流动。

接口

接口初探

1
2
3
4
5
6
function printLabel(labelledObj: { label: string }) {
console.log(labelledObj.label)
}

let myObj = { size: 10, label: 'Size 10 Object' }
printLabel(myObj)

类型检查器会查看 printLabel 的调用。 printLabel 有一个参数,并要求这个对象参数有一个名为 label 类型为 string 的属性。
下面我们重写上面的例子,这次使用接口来描述:必须包含一个 label 属性且类型为 string:

1
2
3
4
5
6
7
8
9
10
11
// 定义接口
interface LabelledValue {
label: string;
}

function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label)
}

let myObj = { size: 10, label: 'Size 10 Object' }
printLabel(myObj)

LabelledValue 接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label 属性且类型为 string 的对象。

可选属性

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

function createSquare(config: SquareConfig): { color: string, area: number } {
let newSquare = { color: 'white', area: 100 }
if (config.color) {
newSquare.color = config.color
}
if (config.width) {
newSquare.area = config.width * config.width
}
return newSquare
}

let mySquare = createSquare({ color: 'black' })

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。

只读属性

一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly 来指定只读属性:

1
2
3
4
interface Point {
readonly x: number;
readonly y: number;
}

你可以通过赋值一个对象字面量来构造一个 Point。 赋值后, x 和 y 再也不能被改变了。

1
2
let p1: Point = { x: 10, y: 20 }
p1.x = 5 // error!

TypeScript 具有 ReadonlyArray类型,它与 Array相似,只是把怕有可变方法去掉了,因此可以确保数组创建后再也不能被修改:

1
2
3
4
5
6
let a: number[] = [1, 2, 3, 4]
let ro: ReadonlyArray<number> = a
ro[0] = 12 // error!
ro.push(5) // error!
ro.length = 100 // error!
a = ro // error!

就算使用赋值也不可以,除非使用类型断言重写:

1
a = ro as number[];

readonly vs const

最简单判断该用 readonly 还是 const 的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用 readonly。

函数类型

© 2019 elaine