安装
安装 typescript 之前需要具有 node 和 npm 环境,检查一下:
$ node -v
v16.14.0
$ npm -v
8.3.1
使用 npm 进行全局安装:
$ npm install -g typescript
安装完成后会有一个 tsc
命令行程序:
$ tsc -v
Version 4.8.2
tsc 是 typescript 编译程序,能将 ts 代码编译为 js 代码。
Hello typescript
编写内容如下的 ts
文件:
const hello = (name: string) => {
return `hello ${name}`
}
hello("zze")
使用 tsc
编译该文件:
$ tsc test.ts
$ ls
test.js test.ts
查看 test.js
文件内容如下:
var hello = function (name) {
return "hello ".concat(name);
};
hello("zze");
数据类型
几种基础类型
let isDone: boolean = false
let age: number = 10
let firstName: string = 'zze'
let message: string = `Hello, ${firstName}`
// undefined 和 null 也是类型
let u: undefined = undefined
let n: null = null
// undefined 和 null 为所有基础类型的子类型,所以可以将 undefined 复制给 number 类型
let num: number = undefined
// any 表示为任意类型,有明确类型时尽量避免使用 any,不然就失去了类型检查的作用
let notSure: any = 4
notSure = 'maybe a string'
notSure = true
notSure.MyName
notSure.getName()
数组和元组
// 数组
let arrOfNumbers: number[] = [1, 2, 3]
arrOfNumbers.push(3)
// 元组,可以限制数组内容中仅包含某几种类型
let user: [string, number] = ['zze', 25]
user.push('zze.xyz')
接口
interface Person {
name: string;
age: number;
}
// 声明该接口类型的变量必须包含接口中已定义的属性并且类型必须相同
let zze: Person = {
name: 'zze',
age: 12
}
函数类型
// 等价于 function add(x: number, y: number, z ?: number): number {
const add1 = (x: number, y: number, z?: number): number => {
if (typeof z === "number") {
return x + y + z;
} else {
return x + y;
}
};
let add2: (x: number, y: number, z?: number) => number = add1;
// 用接口描述函数类型
interface ISum {
(x: number, y: number, z?: number): number;
}
let add3: ISum = add2;
联合类型
// 声明一个变量只能是 string 或 number 类型
let numberOrString: number | string
// 联合类型变量只能使用它们的共有属性和方法,如:
numberOrString.toString()
// 如果访问 string 类型的 length 属性就会报错
numberOrString.length // 报错
// 可以同类型断言指定联合类型变量就是指定类型,比如:
let str = numberOrString as string
// 只能断言为联合类型中存在的类型
let num = numberOrString as number
// typescript 会在不同的类型判断分支中自动确定类型
if (typeof numberOrString === 'string') {
console.log(numberOrString.length)
} else {
console.log(numberOrString.toString().length)
}
枚举
enum Direction {
Up,
Down,
Left,
Right,
}
// 枚举属性会从第一个属性自动从 0 递增赋值
console.log(Direction.Up); // 0
console.log(Direction.Down); // 1
console.log(Direction.Left); // 2
console.log(Direction.Right); // 3
// 可以将枚举用作数组通过下标获取属性字符串
console.log(Direction[0]); // Up
console.log(Direction[1]); // Down
console.log(Direction[2]); // Left
console.log(Direction[3]); // Right
enum Direction1 {
// 第一个枚举属性赋值后,后续属性基于第一个属性值递增
Up = 10,
Down,
Left,
Right,
}
console.log(Direction1.Up); // 10
console.log(Direction1.Down); // 11
console.log(Direction1.Left); // 12
console.log(Direction1.Right); // 13
// 字符串枚举
enum Direction2 {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
// 常量枚举可以提升性能
const enum Direction3 {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
泛型
function add<T>(a: T, b: T): T {
return a + b;
}
let res1 = add(1, 2);
console.log(res1); // 3
let res2 = add("a", "b");
console.log(res2); // ab
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
let res3 = swap(["aaa", 123]);
console.log(res3); // [ 123, 'aaa' ]
function lengthWithArr<T>(arg: T[]): number {
return arg.length;
}
// lengthWithArr 只能接受一个数组类型参数
let res4 = lengthWithArr([1, 2, 3]);
console.log(res4); // 3
interface IWithLength {
length: number;
}
function lengthWithExtends<T extends IWithLength>(arg: T): number {
return arg.length;
}
// lengthWithExtends 可以接受包含 length 属性的类型对象参数
let res5 = lengthWithExtends("aaa");
console.log(res5); // 3
let res6 = lengthWithExtends({ length: 12 });
console.log(res6); // 12
// 泛型类
class Queue<T> {
private data = [] as any[];
push(item: T) {
return this.data.push(item);
}
pop(): T {
return this.data.shift();
}
}
let queue = new Queue<number>();
queue.push(1);
queue.push(2);
console.log(queue.pop().toFixed()); // 1
// 泛型接口
interface KeyPair<T, U> {
key: T;
value: U;
}
let kp1: KeyPair<number, string> = { key: 1, value: "string" };
let kp2: KeyPair<string, number> = { key: "str", value: 2 };
let arr: number[] = [1, 2, 3];
let arrTwo: Array<number> = [1, 2, 3];
评论区