TypeScript学习笔记

本文最后更新于:2024年9月7日 下午 17:20

TypeScript学习笔记

2024/8/28

—— ShizuriYuki

笔记内容来源:

1 基础类型

布尔类型

布尔类型只有 truefalse 两种值。

1
2
let flag: boolean = false;
console.log("布尔类型: ", flag); // 输出: 布尔类型: false

数字类型

TypeScript 支持多种进制的数字类型,包括十进制、二进制、八进制和十六进制。

1
2
3
4
5
6
let a1: number = 10;      // 十进制
let a2: number = 0b1010; // 二进制
let a3: number = 0o12; // 八进制
let a4: number = 0xa; // 十六进制

console.log("数字类型: ", a1, a2, a3, a4); // 输出: 数字类型: 10 10 10 10

字符串类型

字符串可以用双引号(")或单引号(')括起来。

1
2
3
let name: string = "张三";
name = '李四';
console.log("字符串类型: ", name); // 输出: 字符串类型: 李四

数组类型

数组定义有两种方式:使用元素类型加方括号,或使用泛型数组类型。

1
2
3
4
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [4, 5, 6];

console.log("数组类型: ", arr1, arr2); // 输出: 数组类型: [ 1, 2, 3 ] [ 4, 5, 6 ]

元组类型

元组允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

1
2
let tuple: [number, string] = [1, "张三"];
console.log("元组类型: ", tuple); // 输出: 元组类型: [ 1, '张三' ]

枚举类型

枚举是对 JavaScript 标准数据类型的一个补充。使用枚举我们可以定义一些带名字的常量。

1
2
3
4
enum Color { Red, Green, Blue }
let c: Color = Color.Green;

console.log("枚举类型: ", c); // 输出: 枚举类型: 1

任意类型

任意类型(any)允许我们在编译时可选择地包含或移除类型检查。

1
2
3
4
5
let anyType: any = 10;
anyType = "hello";
anyType = true;

console.log("任意类型: ", anyType); // 输出: 任意类型: true

void 类型

void 表示没有任何类型。它常用于定义没有返回值的函数。

1
2
3
4
5
function sayHello(): void {
console.log("Hello World");
}

console.log("void类型: ", sayHello()); // 输出: Hello World 和 undefined

null 和 undefined

nullundefined 是所有类型的子类型。默认情况下,nullundefined 是其他所有类型的子类型,这意味着你可以把 nullundefined 赋值给其他类型。

1
2
3
4
5
6
7
8
9
let n: null = null;
let u: undefined = undefined;

console.log("null和undefined: ", n, u); // 输出: null和undefined: null undefined

let num: number | null = null;
let str: string | undefined = undefined;

console.log("null和undefined赋值: ", num, str); // 输出: null和undefined赋值: null undefined

object 类型

object 表示非原始类型,即除 numberstringbooleansymbolnullundefined 之外的类型。

1
2
let obj: object = { name: "张三" };
console.log("object类型: ", obj); // 输出: object类型: { name: '张三' }

类型断言

类型断言可以用来手动指定一个值的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 尖括号语法
let str1: any = "hello";
let len1: number = (<string>str1).length;
console.log("类型断言1: ", len1); // 输出: 类型断言1: 5

// as 语法
let str2: any = "world";
let len2: number = (str2 as string).length;
console.log("类型断言2: ", len2); // 输出: 类型断言2: 5

function getLength(str: number | string): number {
if ((<string>str).length) {
return (<string>str).length;
} else {
return str.toString().length;
}
}

console.log("类型断言: ", getLength("hello"), getLength(123)); // 输出: 类型断言: 5 3

类型推断

TypeScript 会在没有明确指定类型的时候推测出一个类型。

1
2
3
4
5
let txt;  // any 类型
txt = 100;
txt = "hello";

console.log("类型推断: ", txt); // 输出: 类型推断: hello

2 interface 接口

2.1 属性接口定义

接口用于定义对象的结构,包括只读属性和可选属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface IPerson {
readonly id: number; // 只读属性
name: string;
age: number;
sex?: string; // 可选属性
}

const person: IPerson = {
id: 1,
name: "桃乃木香奈",
age: 23,
sex: "女",
};

console.log("2.1 接口定义: ", person);
// person.id = 2; // Error: 无法为“id”赋值,因为它是只读属性。
// person.money = 100; // Error: 类型“IPerson”上不存在属性“money”。

2.2 接口定义函数

接口可以用于定义函数的形状,通过调用签名实现。

1
2
3
4
5
6
7
8
9
interface ISearchFunc {
(source: string, subString: string): boolean;
}

let mySearch: ISearchFunc = function (source: string, subString: string): boolean {
return source.search(subString) > -1;
};

console.log("2.2 接口定义函数: ", mySearch("hello", "o"));

2.3 可索引类型

接口可以用于定义可索引的类型。

2.3.1 数字索引

使用数字索引来访问数组元素。

1
2
3
4
5
6
interface IStringArray {
[index: number]: string;
}

let myArray: IStringArray = ["Bob", "Fred"];
console.log("2.3.1 数字索引: ", myArray[0]);

2.3.2 字符串索引

使用字符串索引来访问对象属性。

1
2
3
4
5
6
interface IStringArray2 {
[index: string]: string;
}

let myArray2: IStringArray2 = { "0": "Bob", "1": "Fred" };
console.log("2.3.2 字符串索引: ", myArray2["0"]);

2.4 类类型

类可以实现一个或多个接口。接口定义类的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
interface Alarm {
alert(): any;
}

interface Light {
lightOn(): void;
lightOff(): void;
}

class Car implements Alarm, Light {
alert() {
console.log("Car alert");
}
lightOn() {
console.log("Car lightOn");
}
lightOff() {
console.log("Car lightOff");
}
}

const car = new Car();
console.log("2.4 类类型: ", car);
car.alert();
car.lightOn();
car.lightOff();

2.5 接口继承接口

接口可以继承其他接口,从而实现更复杂的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
interface Alarm2 {
alert(): any;
}

interface Light2 {
lightOn(): void;
lightOff(): void;
}

interface AlarmLight extends Alarm2, Light2 {
alertLight(): void;
}

class Car2 implements AlarmLight {
alert() {
console.log("Car2 alert");
}
lightOn() {
console.log("Car2 lightOn");
}
lightOff() {
console.log("Car2 lightOff");
}
alertLight() {
console.log("Car2 alertLight");
}
}

const car2 = new Car2();
console.log("2.5 接口继承接口: ", car2);
car2.alert();
car2.lightOn();
car2.lightOff();
car2.alertLight();

3 class

3.1 类的概念

定义一个基本的 Person 类,它具有 nameage 属性,并包含一个 say 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person {
name: string;
age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

say(): void {
console.log(`我是${this.name},今年${this.age}岁`);
}
}

const person = new Person("桃乃木香奈", 23);
person.say();
// 输出: 我是桃乃木香奈,今年23岁

3.2 继承

定义一个 Student 类继承自 Person 类,并增加 school 属性和 study 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student extends Person {
school: string;

constructor(name: string, age: number, school: string) {
super(name, age);
this.school = school;
}

study(): void {
console.log(`${this.age}岁的${this.name}正在${this.school}学习`);
}
}

const student = new Student("桃乃木香奈", 23, "东京大学");
student.say();
student.study();
// 输出:
// 我是桃乃木香奈,今年23岁
// 23岁的桃乃木香奈正在东京大学学习

3.3 重写

Teacher 类中重写了父类 Personsay 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Teacher extends Person {
school: string;

constructor(name: string, age: number, school: string) {
super(name, age);
this.school = school;
}

say(): void {
super.say();
console.log(`我是${this.school}的老师~`);
}
}

const teacher = new Teacher("桃乃木香奈", 23, "东京大学");
teacher.say();
// 输出:
// 我是桃乃木香奈,今年23岁
// 我是东京大学的老师~

3.4 多态

演示了多态性的应用,父类定义方法,子类重写,在父类引用调用时根据实际对象类型执行相关实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Animal {
name: string;

constructor(name: string) {
this.name = name;
}

eat(): void {
console.log("吃的方法");
}
}

class Dog extends Animal {
eat(): void {
console.log(`${this.name}吃骨头`);
}
}

class Cat extends Animal {
eat(): void {
console.log(`${this.name}吃鱼`);
}
}

function doEat(animal: Animal): void {
animal.eat();
}

const dog = new Dog("小黑");
const cat = new Cat("小花");

doEat(dog); // 输出: 小黑吃骨头
doEat(cat); // 输出: 小花吃鱼

3.5 修饰符

  • public: 公共,可以在任何地方访问。
  • private: 私有,只能在类内部访问。
  • protected: 受保护,可以在派生类中访问。
  • readonly: 只读,只能读取,不能修改。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Movie {
readonly file_max_size: number = 1024;
readonly file_type: string;
public name: string;
private _type: string;
protected _director: string;

constructor(
name: string,
type: string,
director: string,
file_type: string = "mp4",
public file_max_bitrate: number = 384
) {
this.name = name;
this._type = type;
this._director = director;
this.file_type = file_type;
}

get type(): string {
return this._type;
}

set type(type: string) {
this._type = type;
}
}

const movie = new Movie("大话西游", "喜剧", "周星驰", "m3u8");
console.log(movie.file_type); // 输出: m3u8

3.6 存取器

使用 getset 拦截对对象属性的访问和修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class User {
private _name: string;

constructor(name: string) {
this._name = name;
}

get name(): string {
console.log("get name: ", this._name);
return this._name;
}

set name(name: string) {
console.log("set name: (old)", this._name, "=> (new)", name);
this._name = name;
}
}

const user = new User("张三");
user.name = "李四";
console.log(user.name); // 输出: 李四

3.7 静态属性

使用 static 关键字定义静态属性,可以直接通过类名访问。

1
2
3
4
5
6
7
8
9
10
class MathUtils {
static PI: number = 3.1415926;

static add(a: number, b: number): number {
return a + b;
}
}

console.log(MathUtils.PI); // 输出: 3.1415926
console.log(MathUtils.add(1, 2)); // 输出: 3

3.8 抽象类

抽象类是供其他类继承的基类,不能直接实例化。抽象方法必须在派生类中实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
abstract class Device {
protected readonly deviceType: string;

constructor(deviceType: string) {
this.deviceType = deviceType;
}

abstract turnOn(): void;
abstract turnOff(): void;
}

class Computer extends Device {
private readonly computerUUID: string;

constructor() {
super("Computer");
this.computerUUID = Math.random().toString(16).slice(2);
}

turnOn(): void {
console.log(`${this.deviceType} UUID: ${this.computerUUID} 开机`);
}

turnOff(): void {
console.log(`${this.deviceType} UUID: ${this.computerUUID} 关机`);
}
}

const computer = new Computer();
computer.turnOn(); // 输出: Computer UUID: <随机UUID> 开机
computer.turnOff(); // 输出: Computer UUID: <随机UUID> 关机

TypeScript学习笔记
https://qalxry.github.io/2024/09/07/TypeScript学习笔记/
作者
しずり雪
发布于
2024年9月7日
更新于
2024年9月7日
许可协议