这是我参与「第五届青训营」笔记创作活动的第9天(之前天数有误)。今天主要是记录老师讲解的TypeScript基本知识。
一、本堂课重点内容:
TypeScript基本知识。
二、详细知识点介绍:
基本数据类型
布尔值
let isDone: boolean = false;
这里记录一个老生常谈的问题:使用构造函数Boolean创造的对象不是布尔值,如果说是
let isDone: boolean = new Boolean(1);
那么会引发TS编译报错。事实上 new Boolean() 返回的是一个 Boolean 对象。不过直接调用 Boolean 也可以返回一个 boolean 类型。
let isDone: boolean = Boolean(1);
数字
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
console.log(isNaN(notANumber));
let infinityNumber: number = Infinity;;
字符串 ts中的字符串string类型包含了普通字符串和模板字符串。
let firstName: string = 'Tom'
// 模板字符串
let msg: string = `Hello, ${decLiteral}, ${firstName}`;
空值void JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数。之所以这里强调是函数返回值类型,是因为声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined(在非严格模式下还可以指定为null):
function alertName(): void {
alert('My name is Tom');
}
undefined 和 null
let u: undefined = undefined;
let n: null = null;
与 void 的区别是,undefined 和 null 是所有类型的子类型。在非严格模式下,undefined 类型或者 null 类型的变量,可以赋值给 number 类型的变量:
let num: number = undefined;
而声明变量的数据类型为 void 时,非严格模式下,变量的值可以为 undefined 或 null。
任意值any
如果是一个普通类型,在赋值过程中改变类型是不被允许的;但如果是 any 类型,则允许被赋值为任意类型。并且在任意值上访问任何属性和方法都是允许的(这里的允许指的是可以通过编译,但是在运行时依然会导致报错)。
let notSure: any = 4;
notSure = 'maybe it is a string';
notSure = true;
notSure.myName = 'xx';
notSure.getName();
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型:
let something;
something = 'seven';
something = 7;
something.setName('Tom');
联合数据类型 UnionType
当我们想表示某个变量可以是某几种类型中的一种,但是又希望限定它不会是这几种以外的类型,那么就可以使用 | 来表示联合类型。
let numberOrString: number | string;
numberOrString = 123;
numberOrString = 'sss';
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
function getLength(something: string | number): number {
return something.length;
}
上例中,length 不是 string 和 number 的共有属性,所以会报错。访问 string 和 number 的共有属性是没问题的:
function getString(something: string | number): string {
return something.toString();
}
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
console.log(myFavoriteNumber.length);
myFavoriteNumber = 7
数组
无论是哪一种表示方法,除了any[]外,数组的项中不允许出现其他的类型。而且数组的一些方法的参数也会根据数组在定义时约定的类型进行限制。
let array: number[] = [1, '1', 2, 3, 5]; // 报错
let fibonacci: number[] = [1, 1, 2, 3, 5];
fibonacci.push('8'); // 报错
数组有三种基本表示方法:
- 「类型 + 方括号」表示法。就是我们前面广泛使用的方法,这种方法最简便。
let arrOfNumbers: number[] = [1, 2, 3, 4, 5, 6]; arrOfNumbers.push(7); - 数组泛型(Array Generic) Array<elemType> 来表示数组
let fibonacci2: Array<number> = [1, 1, 2, 3, 5] - 用接口表示数组。用接口来表示数组比前2种麻烦很多,常用来表示类数组。
interface NumberArray { [index: number]: number; } let fibonacci: NumberArray = [1, 1, 2, 3, 5];
类数组
类数组(Array-like Object)不是数组类型,比如函数中的 arguments:
function test() {
// arguments 有数组的一些属性。但是缺少一些数组的基本方法,如foreach
console.log(arguments);
arguments[0];
arguments.length;
// let arr: any[] = arguments; // 也会报错
}
arguments 实际上是一个类数组,不能用普通的数组的方式来描述,而应该用接口:
function sum () {
let args: {
[index: number]: number;
length: number;
callee: Function;
} = arguments;
}
在这个例子中,我们除了约束当索引的类型是数字时,值的类型必须是数字之外,也约束了它还有 length 和 callee 两个属性。事实上常用的类数组都有自己的接口定义,如 IArguments, NodeList, HTMLCollection 等。其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是我们上面用于承接 arguments 的接口:
function sum2() {
let args: IArguments = arguments;
}
元组 tuple
元组 tuple 可以让不同数据类型的元素处于同一“数组”中,可以认为是限定了 成员位置、对应类型 的数组。
let users: [string, number] = ['va', 1];
如果赋值的个数、对应位置的类型不对均会报错。
三、实践练习例子:
例子已经在文章中举出。
四、课后个人总结:
本章的知识点需要大量的实例和参考资料来辅助理解。
五、引用参考:
我主要是基于老师讲解提供的代码仓库进行理解和分析,并记录了自己的心得。