原始数据类型
鉴于TypeScript和JavaScript之间的紧密联系,我们首先需要清楚JavaScript的原始数据类型有哪些:
- 布尔值 boolean
- 数值 Number
- 字符串 string
- null
- undefined
- Symbol(来自ES6)
- BigInt(来自ES10)
以上,前五种来自ES5,后面两种诞生较迟。
let isDone: boolean = flase
let num: number = 9
let str: string = 'Tom'
let sentence: string = `My name is ${str}`
function sayHello(): void {
console.log('Hello!' + sentence)
}
let un: undefined = undefined
在TypeScript中,还有一种重要的数据类型——元组(tuple)。
// 如下即声明了一个元组:一对值为string、number的元组
let mar: [string, number] = ['Mar', 28]
// 访问元组的元素:索引下标访问即可
console.log(mar[0]);
console.log(mar[1]);
// 此时,若向mar中再添加元素,添加的第一个只能是字符串,第二个只能是number
mar.push('Hah')
mar.push(90)
任意值
对于规定了数据类型的变量,在赋值过程中不允许被改变类型,否则报错。
但是规定为any类型,则是可以被赋值为任意类型的。
let anything: any = 'Tom'
console.log(anything.name);
console.log(anything.age); // 均输出 undefined
类型推论
类型推论规则:在变量赋值时,虽然有时候并没有指定类型,但是会根据赋值的结果自动推断其类型。
let str = 'Hello' // 会根据'Hello'自动将str规定为string类型
let anyone // 若没有赋值,则自动为any类型
联合类型
使用 | 将多个可能的数据类型分隔。
let identity: string | number // 允许identity变量是string或者number类型
identity = '872092'
identity = 872092
但是,即使是联合类型的变量,在赋值时也会根据类型推论的规则,推断出来一个类型。
接口
接口是对行为的抽象,此外,在TypeScript中,它也常用于对对象的形状进行描述。
// interface就是接口的关键字
interface Person {
name: string;
age: number;
readonly indentity: string | number; // readonly 表示成员只读
birthPlace?: string; // ?表示可选属性,允许变量与接口在该成员上的不完全匹配
[propName: string | number]: any // 表示可选属性和确定属性都必须是string或者number类型
}
// 定义的变量中,必须严格按照接口来声明成员,多一个、少一个都不可以
let tom: Person = {
name: 'Tom'
};
- readonly关键字,用于声明某一成员为只读属性,注意这个只读是针对第一次给对象赋值时候的约束,而不是第一次给该只读属性赋值时。
- [propName: string],表示定义了任意属性取string类型的值
数组类型
let fibonacci: number[] = [1, 1, 2, 3, 5]
let fibonacci2: Array<number> = [1, 1, 2, 3, 5]
接口中也可以描述数组:
interface NumberArray {
// 表示:只要索引(下标)类型是数字,那么值的类型必须是数字
[index: number]: number
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5]
函数类型
函数的两种写法:函数声明和函数表达式,它们的TypeScript写法如下:
// 定义两数相加的函数
// 函数声明
function sum(x: number, y: number): number {
return x + y
}
console.log(sum(1, 1)); // 2
// 函数表达式
// TypeScript的完整写法
let mySum: (x: number, y: number) => number = function(x: number, y: number): number {
return x + y
}
console.log(mySum(1, 1)); // 2
当然,由于函数表达式的写法较为繁琐,有时也可以采用接口方式声明。
// 用接口定义函数形状
interface SearchFunc {
(source: string, subString: string): boolean
}
let mySearch: SearchFunc
// 函数:判断一个字符串是否为另一个字符串的子串
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1
}
console.log(mySearch('Hello, JavaScript!', 'Hello'))
函数重载
函数重载是为了准确地声明函数的接收参数和返回类型。
// 函数重载
// 函数功能: 接收参数,若为数字123,则返回321,若为字符串'123',则返回'hello'
function reverse(x: number): number
function reverse(x: string): string
// 定义函数
function reverse(x: number | string): number | string | void {
if( typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''))
} else if ( typeof x === 'string' ) {
return x.split('').reverse().join()
}
}
类型断言
类型断言,即Type Assertion,用于手动指定一个值的类型。语法如:值 as 类型
用途
- 将一个联合类型断言为其中一个类型,因为有时候我们确实需要其中一个类型特有的方法或者属性。
- 父类可以被断言为子类
- 任何类型都可以被断言为any
- any可以被断言为任何类型
类型断言的限制
// 只有在兼容情况下,才可以使用断言
// 兼容:可以类比为面向对象里的继承,下面的栗子中,我们可以说,Animal兼容Cat
interface Animal {
name: string
}
interface Cat {
name: string
run(): void
}
// Animal和Cat可以相互断言
内置对象
内置对象,是指根据标准,在全局作用域上存在的对象,这里的标准指ECMAScript和其他环境(如DOM)的标准。
ES的内置对象
包括:
- Boolean
- Error
- Date
- RegExp等
DOM和BOM中的内置对象
包括:
- Document
- HTMLElement HTML元素
- Event 事件
- NodeList 节点列表