当前位置: 首页> 游戏> 游戏 > 【TS】进阶

【TS】进阶

时间:2025/7/23 5:12:40来源:https://blog.csdn.net/weixin_63681863/article/details/139502391 浏览次数:1次

一、类型别名

类型别名用来给一个类型起个新名字。

type s = string;
let str: s = "123";
type NameResolver = () => string;: 
// 定义了一个类型别名NameResolver,它是一个函数类型。这个函数没有参数,返回值类型为string。这意味着任何被标记为NameResolver的变量都将是一个无参函数,它返回一个字符串。

类型别名常用于联合类型。

type all = string | number | boolean;
let a: all = 2323;

二、字符串字面量类型

type stringType = "ssss" | "wwww" | "rrrr";
let userName: stringType = "rrrr";
let userName2: stringType = "@@@"; // Type '"@@@"' is not assignable to type 'stringType'.

注意,类型别名与字符串字面量类型都是使用 type 进行定义。

三、元组 Tuple

数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。

let tom: [string, number];
tom[0] = 'Tom';
tom[1] = 25;tom[0].slice(1);
tom[1].toFixed(2);

但是当直接对元组类型的变量进行初始化或者赋值的时候,需要提供所有元组类型中指定的项。

let tom: [string, number];
tom = ['Tom', 25];let tom: [string, number];
tom = ['Tom']; // Property '1' is missing in type '[string]' but required in type '[string, number]'.

当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:

let tom: [string, number];
tom = ['Tom', 25];
tom.push('male');
tom.push(true); // Argument of type 'true' is not assignable to parameter of type 'string | number'.

四、枚举

4.1 简单例子

// 使用枚举类型给一组数值赋予名称
// 可以通过 名称去拿值,也可以通过值拿名称
enum NumberType {one,two,three,
}
console.log(NumberType);

在这里插入图片描述

4.2 手动赋值

我们也可以给枚举项手动赋值:

enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true

不手动赋值,就默认是从0开始,后面递增
在这里插入图片描述
如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点的:

enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 3); // true
console.log(Days["Wed"] === 3); // true
console.log(Days[3] === "Sun"); // false
console.log(Days[3] === "Wed"); // true

手动赋值的枚举项可以不是数字,此时需要使用类型断言来让 tsc 无视类型检查 (编译出的 js 仍然是可用的):

enum Days {Sun = 7, Mon, Tue, Wed, Thu, Fri, Sat = <any>"S"};
var Days;
(function (Days) {Days[Days["Sun"] = 7] = "Sun";Days[Days["Mon"] = 8] = "Mon";Days[Days["Tue"] = 9] = "Tue";Days[Days["Wed"] = 10] = "Wed";Days[Days["Thu"] = 11] = "Thu";Days[Days["Fri"] = 12] = "Fri";Days[Days["Sat"] = "S"] = "Sat";
})(Days || (Days = {}));

当然,手动赋值的枚举项也可以为小数或负数,此时后续未手动赋值的项的递增步长仍为 1:

enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1.5); // true
console.log(Days["Tue"] === 2.5); // true
console.log(Days["Sat"] === 6.5); // true

4.3 常数项和计算所得项

枚举项有两种类型:常数项(constant member)和计算所得项(computed member)。

前面我们所举的例子都是常数项,
一个典型的计算所得项的例子:

enum Color {Red, Green, Blue = "blue".length};

注意,计算所得项必须是最后一项,后面不要再有东西了,因为后面计算不出来
除非后面的有手动赋值

enum Color {red,blue = "blue".length,green = 4,
}

4.4 常数枚举

常数枚举是使用 const enum 定义的枚举类型:

const enum Directions {Up,Down,Left,Right
}let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员。

上例的编译结果是:

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];

假如包含了计算成员,则会在编译阶段报错:

const enum Color {Red, Green, Blue = "blue".length};// index.ts(1,38): error TS2474: In 'const' enum declarations member initializer must be constant expression.

但是这种是可以的:

const enum Color {Red, Green, Blue = 11};

4.5 外部枚举

主要用在声明文件
外部枚举(Ambient Enums)是使用 declare enum 定义的枚举类型:

declare enum Directions {Up,Down,Left,Right
}let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

之前提到过,declare 定义的类型只会用于编译时的检查,编译结果中会被删除。

上例的编译结果是:

const enum Color {Red, Green, Blue = "blue".length};
var directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

declare 定义的类型只会用于编译时的检查,编译结果中会被删除。
上例的编译结果是:

var directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

同时使用 declare 和 const 也是可以的:

declare const enum Directions {Up,Down,Left,Right
}let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

编译结果:

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];

五、类

http://ts.xcatliu.com/advanced/class.html

5.1 属性和方法

// 类:描述了所创建的对象共同的属性和方法
// 实例化对象
class Person {// 首先定义属性name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHi(str: string) {console.log("hi", str);}
}let p = new Person("slx", 14); // new的时候,回执行构造函数
p.sayHi("slx");

5.2 继承

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法

// 通过继承,扩展现有的类
// 子类继承父类
class Animal {// 父类name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHi(str: string) {console.log("hi", str);}eat(str: string) {console.log("吃什么呀,吃这个", str);}
}// 子类
class Dog extends Animal {constructor(name: string, age: number) {super(name, age);}// 不写父类的方法,也依然可以调用eat(): void {console.log("子类的eat");super.eat(""); // 当然也可以在里面调用父类的方法}
}const c = new Animal("猫猫", 1);
const d = new Dog("修勾", 3);
d.sayHi("修勾");
d.eat();

类与类之间的存在继承关系,通过extends继承;
子类可以通过super调用父类方法和构造函数;

5.3 存取器

通过getter和setter 可以改变属性的赋值和读取行为,控制对对象成员的访问

class Name {firstName: string;lastName: string;constructor(firstName: string, lastName: string) {this.firstName = firstName;this.lastName = lastName;}get fullName() {return this.firstName + "-" + this.lastName;}
}let n = new Name("张", "凌");
console.log(n);
关键字:【TS】进阶

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: