数据类型
原始类型
最新的 ECMAScript 标准定义8种数据类型
- Boolean
- Null
- Undefined
- BigInt
- String
- Symbol
- Object
TS声明原始数据类型
let isDone: boolean = false
let age: number = 10
let name: string = 'Actoress'
let u: undefined = undefined
Any 类型
TS的任意类型,可以任意调用方法和属性,尽量避免使用
数组和元组
数组
let arrOfNumbers: number[] = [1, 2, 3] // number类型数组
元组
// 定义元组,如果元组定义时是两项,那么必须为两项且每一项的数据类型必须对应
// 可以使用 push 来改变数组长度,但是 push 的数组类型必须为定义数据类型之一
let user: [string, number] = ['name', 12]
注意:类数组
类型无法使用any[]
定义
// 类数组拥有部分数组的属性,例如 length,但是没有部分方法例如 forEach 等
// 常见的类数组 IArguments,HTMLCollection
function test () {
console.log(arguments) // arguments 的类型为类数组(IArguments)
}
Interface 接口
只会被用来做类型的静态检查,不会被编译到JS中去
Interface 主要功能:
- 对对象的形状(shape)进行描述;
- Duck Typing(动态语言中的一种对象推断的策略)
// 定义接口
interface IPerson {
name: string;
age: number;
}
// 使用接口定义变量,属性必须与接口一致,不能增删属性
let person: IPerson = {
name: 'Actoress',
age: 20
}
类型推论
TS会在没有明确指定类型的时候,推测出一个类型
联合类型
// 定义一个联合类型
let numberOrString: number | string
// 将一个联合类型认为是什么某个类型
function getLength (input: string | number): number {
const str = input as string // 暂定类型
if (str.length) {
return str.length
} else {
const number = input as number
return number.toString().length
}
// typeof 中会智能缩小范围
function getLength (input: string | number): number {
if (typeof input === 'string') {
return input.length
} else {
const number = input as number
return number.toString().length
}
}
Class 类
ES6中的类
// 创建一个普通类
class Animal {
constructor (name) {
this.name = name
}
run () {
return `${this.name} is running`
}
}
const snake = new Animal('lily')
console.log(snake.run())
// 继承
class Dog extends Animal {
bark () {
return `${this.name} is barking`
}
}
// 多态
class Cat extends Animal {
static category = ['mammal'] // 可直接访问的静态属性,不需要实例化
constructor (name) {
super(name) // 重写构造函数
console.log('name')
}
run () {
return 'new:' + super.run() // 重写并调用父类方法
}
}
TS中的修饰符
- Public: 修饰的属性或方法是共有的
- Private: 修饰的属性或者方法是私有的,修饰的变量/方法不允许访问或者修改
- Protected: 修饰的属性或方法是受保护的,修饰的变量/方法只有子类可以访问
- readonly: 只读属性
类和接口
// 当两个类需要找到一个合适的父类,但是又没有合适的,可以使用接口
interface Start {
// void 表示什么都不返回
switchStart(trigger: boolean): void;
}
interface Battery {
checkBatteryStatus(): void;
}
// 接口继承
interface NewBattery extends Battery {
ChargeBattery(): void;
}
// 类实现接口定义的方法
class Car implements Start {
start (trigger: boolean) {}
}
// 类实现接口定义的方法,实现多个接口
class Phone implements Start, Battery {
start (trigger: boolean) {}
checkBatteryStatus () {}
}
Enums 枚举
定义一个基础枚举
enum Direction {
Up,
Down,
Left,
Right
}
console.log(Direction.Up) // => 0
console.log(Direction[0]) // => 'Up'
枚举的自动递增
enum Direction {
Up = 10, // 手动赋值
Down, // 未手动赋值的枚举项会接着上一个赋值的自动递增
Left,
Right
}
console.log(Direction.Up) // => 10
console.log(Direction.Down) // => 11
字符串枚举
enum Direction {
Up = 'UP', // 手动赋值
Down = 'DOWN', // 未手动赋值的枚举项会接着上一个赋值的自动递增
Left = 'LEFT',
Right = 'RIGHT'
}
console.log(Direction.Up) // => 'UP'
常量枚举(可以提升性能)
const enum Direction {
Up = 'UP', // 手动赋值
Down = 'DOWN', // 未手动赋值的枚举项会接着上一个赋值的自动递增
Left = 'LEFT',
Right = 'RIGHT'
}
console.log(Direction.Up) // => 'UP'
Generics 泛型
在定义 函数 / 接口 / 类 的时候不预先指定类型,而是在使用的时候指定类型
// 定义泛型,T 为泛型名称
function echo<T>(arg: T): T {
return arg
}
const str: string = 'str'
const result = echo(123)
// 多个泛型,元组
function swap (tuple) {
return
}