TypeScript
TypeScript 是一种由微软开发的开源编程语言,它是 JS 的一个超集,设计目的在于增强 JS 的开发效率和维护性。
TS 在 JS 的基础上添加了静态类型,使得开发者能在编码阶段就发现类型错误,提高了代码的健壮性和可维护性。
特性:
- 静态类型系统:允许在编译时进行类型检查
- 增强面向对象特性:支持类、 接口、模块、泛型等
不支持直接在浏览器运行,需要先编译成 js 代码。
安装
npm install -g typescript
pnpm add -D typescript
验证:
tsc -v
如果是局部安装的,需要使用 npx 运行:
npx tsc -v
初始化,会在根目录生成一个tsconfig.json
文件
npx tsc --init
编译
经过编译,可以得到一个同名的 js 文件
tsc helloworld.ts
#如果不在根目录下,要加反斜杠
tsc .\src\helloworld.ts
也可以用ts-node
插件直接在终端查看结果,但不会生成 js 文件
npm install -g ts-node
运行:
ts-node helloworld.ts
类型
const isDone: boolean = false; // 布尔
const num: number = 6; // 数字
const str: string = 'zgh'; // 字符串
const obj: object = {}; // 对象
const u: undefined = undefined;
const n: null = null;
字面量类型
字面量类型是比原始类型更精确的类型,是原始类型的子类型。主要包括字符串、数字、布尔、对象。
示例:使用 string 可以表明是什么类型,但是不知道具体的值。使用字面量类型就是要求值也一样
let str1: string = 'hello';
let str2: 'world' = 'world';
const count: 1 = 1;
const isTrue: true = true;
通常和联合类型一起使用:
const str: 'hello' | 'world' = 'hello';
使用 const 声明的原始变量,其类型会从值推导出最精确的字面量类型。如:
let t1 = 'hello'; // let t1: string
const t2 = 'world'; // const t2: "world"
object 类型
const p1: object = {};
const p2: object = [];
const p3: object = () => {};
在有些情况下,推荐使用以下的方式代替 object
,进行更详细的区分
Record<string, unknown>
或Record<string, any>
表示对象unknown[]
或any[]
表示数组(...args: any[]) => any
表示函数
null 和 undefined
undefined
和 null
是所有类型的子类型。
const tmp1: null = null;
const tmp2: undefined = undefined;
const tmp3: string = null;
const tmp4: string = undefined;
最后两行会报错。可以在 tsconfig.json 中关闭 strictNullChecks,设置"strictNullChecks": false
数组类型
数组类型的表示方法:
- 类型 + 方括号:
number[]
、string[]
- 数组泛型:
Array<T>
interface
,较复杂,一般不用
const arr1: number[] = [1, 2, 3];
const arr2: Array<number> = [4, 5, 6];
interface NumberArray {
[x: number]: number;
}
let arr3: NumberArray = [1, 2, 3];
const arr4: (number | string)[] = [1, 'a', 'b', 2]; // 不知道元素数量,类型已知
对象数组的类型注解:
const arr: { name: string; age: number }[] = [
{ name: 'tom', age: 18 },
{ name: 'jack', age: 19 }
];
如果有同样类型的数组,可以用 类型别名,或者使用 类
type Person = {
name: string;
age: number;
};
const arr: Person[] = [
{ name: 'tom', age: 18 },
{ name: 'jack', age: 19 }
];
tuple 元组类型
元组 Tuple,表示一个已知元素数量和类型的数组。注意:元组的长度固定
示例 1:
const tuple: [string, number, boolean] = ['hello', 123, true];
tuple[3]; // ts会报错
长度为 3 的元祖类型在索引 3 处没有元素,所以报错。如果使用 tuple.push({})
会报错,因为只能添加元组中已经存在的类型。
示例 2:
const tuple: [string, number, boolean] = ['hello', 123, true];
tuple.push(1);
console.log(tuple); // ['hello', 123, true, 1]
console.log(tuple[3]); // ts会报错,但是能打印出1
报错原因是 tuple 被定义为一个长度固定为 3 的元组类型。访问索引 3 超出了元组的长度范围。但是实际上变量已经被添加了。
如果要严格限制,可以用 readonly
关键字,如:
const tuple: readonly [string, number, boolean] = ['hello', 123, true];
tuple.push(1); // ts报错
示例 3:可选成员
const tuple: [string, number, boolean?] = ['hello', 123];
示例 4:解构赋值
const tuple: [string, number] = ['ha', 666];
const [ha, info] = tuple;
Symbol
类型
const sym = Symbol();
let obj = {
[sym]: 'zgh'
};
console.log(obj[sym]); // zgh
枚举类型
enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
let dir: Direction = Direction.NORTH;
console.log(dir); // 0
let dirName: string = Direction[2];
console.log(dirName); // EAST
Any
类型
即任意类型,ts 允许对 any 类型的值进行任何操作
let notSure: any;
notSure.user.name; // ok
notSure[0]; // ok
notSure(); // ok
new notSure(); // ok
unknown
类型
就是不知道啥类型,只能被赋值给any
类型和unknown
类型本身
let unk: unknown;
unk.user.name; // Error
unk(); // Error
new unk(); // Error
let value: unknown;
let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
let value5: string = value; // Error
let value6: object = value; // Error
let value7: any[] = value; // Error
let value8: Function = value; // Error