愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

Typescript(壹):基础类型与变量声明

一、TS的基础类型

typescript除了兼容JavaScript本身就具有的数据类型外,还支持一些它独特的数据类型,所以typescript共支持以下的基本数据类型:

object、boolean、number、string、null、undefined、数组、元组、枚举、any、void、never

在typescript里使用类型声明的形式为:varName: 类型名称,例如:

let name: string = 'RuphiLau'
let age: number = 21
let isBoy: boolean = true

JavaScript里就有的数据类型使用方法如上,而以下是对其他数据类型的介绍:

1、数组

数组类型的声明有两种方式:类型[]或者Array<类型>,例子如:

let scores: number[] = [100, 98, 99]
let names: Array<string> = ['Tom', 'Jack']

2、元组

元组表示的是已经明确知道元素个数及元素类型的数组,元组中每个元素的类型不必都相同,如:

let nameAndAge: [string, number] = ['RuphiLau', 21]
// 而以下的语句则是不合法的
let nameAndAge: [string, number] = [21, 'RuphiLau']

而当数组越界时,会使用联合类型进行检查,而这个联合类型就是元组里出现过的类型的组合:

let x: [string, number] = ['A', 123]
x[2] = 'B' // 可以,因为'A'符合`string | number`这一联合类型
x[3] = 456 // 同样可以
x[4] = true // 不行,因为true是boolean,不符合`string | number`

3、枚举

枚举的概念和其他语言一样,可以用它来为一组值赋予语义化的名字,如:

enum Color {
    Red,
    Green,
    Blue
}

默认情况下,枚举值将从0开始编号,即Color.Red等于0,Color.Green等于1,以此类推。当然,我们也可以改变这种赋值顺序,如:

enum Color {
    Red,
    Green = 3,
    Blue
}

这时候,Color.Green就等于3,而Color.Blue就等于4了,当然,还可以选择对每个枚举项都赋予一个值,如:

enum Color {
    Red = 1,
    Green = 2,
    Blue = 3
}

有时候,我们想要通过枚举值来反推枚举的名称,那么这种情况下,可以这么写:

Color[Color.Blue]

就能得到Blue

4、Any

any用于指定那些编译阶段还不能明确值类型的变量,相当于在编译时告诉编译器不去检查该变量的类型,如:

let input: any = readWhenUsersInput()
let list: any[] = [1, 'Hello', false]

5、Void

void表示没有值,一般可以用于对函数返回值类型的声明中:

function greet(): void {
    console.log('Hello, world')
}

当然也可以指定变量的类型为void,但是如果变量的类型为void,那么就只能接受两种赋值:nullundefined,如:

let someVar: void = null
let someVar2: void = undefined

5、null和undefined

nullundefined是任何类型的子类型,所以可以用它们来为任何类型的变量赋值,如:

let n: number = null

如果指定了--strictNullChecks标记,那么null就只能赋值给它自身,如:

let a: null = null // 可以
let b: void = null // 报错
let c: void = undefined // 可以
let d: null = undefined // 报错

6、Never

never表示的是那些永不存在的值的类型,比如有:总是抛出异常的函数、根本不会有返回值的函数,如:

function foo(): never {
    throw new Error('error')
}

function foo(): never {
    while(true) {
    }
}

never类型是任何类型的子类型,可赋给任何类型;但never没有子类型,所以除了never本身外,没有类型可以赋给never,即使any也不行

7、Object

object表示的是 非原始类型,也就是除了number/string/boolean/symbol/null/undefined外的类型。所以可以用Object表示Object.create这样的API,如:

declare function create(o: object | null): void

create({ prop: 0 }) // OK
create(null) // OK
// 以下的则都会报错
create(123)
create('string')
create(false)
create(undefined)


二、TS的类型断言

TS允许明确表示一个值的类型是什么,这主要用在我们编写程序时明确知道值是什么类型,TS不会去检查这个值的类型,因为它会假设我们已经很清楚这个值的类型了,这种方式称为类型断言,写法有两种:
1)使用<类型>语法,如:console.log(<string> username),但是在jsx里,由于会造成冲突,所以不能用这种形式
2)使用as语法,如:console.log(username as string)


三、变量声明

typescript里的变量声明支持ES6里的letconst,用法与ES6基本一致