报菜名(基础类型)
本章主要搞定基础数据类型和复杂数据类型:
-
JS 的基础数据类型报菜名:
- number
- string
- boolean
- null
- undefined
- ES6 新增 symbol
- ES2020(ES11)新增 bigint。
- 复杂数据类型是 object,这些类型在 TS 中都有对应类型:
// 基础类型
const age: number = 24;
const name: string = 'xiaoming';
const male: boolean = false;
const nul: null = null;
const undef: undefined = undefined;
// 基础类型(新增)
const symbolVar: symbol = Symbol('unique');
const bigintVar1: bigint = 90342342342345n;
const bigintVar2: bigint = BigInt(85464564540991);
// 复杂类型
const obj: object = { name, age, male };
复制代码
其中,除了 null 与 undefined 外,余下的类型基本上可以完全对应到 JavaScript 中的数据类型概念。
所以下面只聊这两个:
null 与 undefined
在 JS 中,二者的含义是 :
- null: 这有值,值为空。
- undefined: 这没值。
而在 TS 中,null 与 undefined 都是有具体意义的类型,不开 strictNullChecks 检查时,二者会被视作其他类型的子类型,例如:
// 基础声明
const tmp1: null = null;
const tmp2: undefined = undefined;
// 不开 strictNullChecks 时成立
const tmp3: string = null; // 此时可以给sting类型赋值null
const tmp4: string = undefined; // 同上,此时可以给sting类型赋值undefined
复制代码
除了这两个类型外,TS 中还有一个特殊类型:void
void
void 用于描述一个内部没有 return 语句,或者没有显式 return 一个值的函数的返回值;描述的是空返回值。
function func1() {}
function func2() {
return;
}
function func3() {
return undefined;
}
复制代码
三者返回值都是 undefined:
- func1 与 func2 的返回值类型会被隐式推导为 void。
- func3 显式返回 undefined,所以返回值类型是 undefined。
虽然 func3 的返回值类型会被推导为 undefined,但是你仍然可以使用 void 类型进行标注,因为在类型层面 func1、func2、func3 都表示 “没有返回一个有意义的值”。
数组
数组是前端最常用的类型之一,在 TS 中有两种声明类型方式。
- arr1、arr2 两种方式完全等价,但前者用的更多。
const arr1: string[] = [];
const arr2: Array<string> = [];
// 不报错
const arr3: string[] = ['apple', 'banana', 'orange'];
console.log(arr3[100]);
// 报错:长度为“3”的元组类型“[string, string, string]”在索引“599“处没有元素
const arr4: [string, string, string] = ['apple', 'banana', 'orange'];
console.log(arr4[100]);
复制代码
数组的子集:元组(Tuple) ,元组是已知元素数量和类型的数组,用来防止出现访问越界的情况。
相比数组,元组可以给内部的每个元素都精确地声明具体类型 or 可选类型 :
// 不能明确清楚数组内值的类型
const arr5: any[] = ['apple', 666, true];
// 能明确知道每个值的具体类型
const arr5: [string, number, boolean] = ['apple', 666, true];
// 还能给元组声明可选类型,此时元组长度为1
const arr6: [string, number?, boolean?] = ['apple'];
// 下面这么写也可以,但元组长度是2
const arr6: [string, number?, boolean?] = ['apple', ,];
// 元组长度是3
const arr6: [string, number?, boolean?] = ['apple', , ,];
复制代码
当然,前端实际开发场景中一般很少声明元组,了解就好。
对象
JS 数据类型的重中之重,也是本节最重要部分。需要了解:
- TS 中如何声明对象
- 修饰对象属性
01 | 如何声明对象
在 TypeScript 中我们需要特殊的类型标注来描述对象类型,即 interface
interface user {
name: string;
age: number;
male: boolean;
}
const obj1: user = {
name: 'codeMax',
age: 18,
male: true,
};
复制代码
对于 interface 的声明:
- 对象实例中的每一个属性,都必须一一对应到接口的属性类型。
- 在对象内部声明,或
obj1.other = 'xxx'
这样形式赋值的属性 / 方法,interface 类型都要声明到。
02 | 修饰对象属性
除了声明属性以及属性的类型以外,我们还可以对属性进行修饰,常见的修饰包括可选(Optional) 与 只读(Readonly) 两种。
interface user {
name: string;
age: number;
male?: boolean;
func?: Function;
}
const obj2: user = {
name: 'codeMax',
age: 18,
// 不写male,func也不会报错,因为这两个属性/方法是可选项
};
复制代码
在这种情况下,即使你在 obj2 中定义了 male 属性,但当你访问 obj2.male 时,它的类型仍然会是 boolean | undefined
,因为它是可选类型。
除了可选,还可以对属性 / 方法进行只读修饰,它的作用是防止对象的属性被再次赋值。
interface user {
readonly name: string;
age: number;
}
const obj3: user = {
name: 'codeMax',
age: 18,
};
obj3.name = 'LiLei' // 无法分配到 "name" ,因为它是只读属性
复制代码
并且在数组与元组层面也有着只读的修饰,但与对象不太一样。
- 只能将整个数组 / 元组标为只读,而不是像对象这样,某个属性 / 方法只读。
- 一但标记为只读,那对应数组 / 元组将不再有 push、pop 等方法(即能修改原数组的方法)。因此报错信息也将是类型 xxx 上不存在属性 “push” 。这一实现的本质是只读数组与只读元组的类型实际上变成了 ReadonlyArray,而不再是 Array。
总结
本节介绍了 TS 中的基础数据类型(7 种) + 复杂数据类型(数组 / 元组、对象),以及修饰属性:可选 | 只读。 东西不多,而且很多内容跟 JS 有重叠。一天看一遍,看三天,包你能掌握 70%!