本文说明:TypeScript 相关文章,了解更多特性。
网页编辑器: https://www.typescriptlang.org/zh/play
概念:当某个函数只有一个参数,且希望该参数是某个类型或另一个类型时,就采用 联合类型
案例:检查某个值是否落在特定区间内
// 检查某个值是否落在特定区间内
// 接收 string 值 | number 值
class RangeValidationBase {
// 目标区间: 最小值 和 最大值
constructor(private start: number = 0, private end: number = 10) {}
protected RangeCheck(value: number) : boolean {
return value >= this.start && value <= this.end;
}
protected GetNumber(value: string) : number {
return new Number(value).valueOf();
}
}
// 只接受 string | number
class UnionRangeValidation extends RangeValidationBase {
IsInRange(value: string | number) : boolean {
if (typeof value === "number") {
return this.RangeCheck(value);
}
return this.RangeCheck(this.GetNumber(value));
}
}
输出结果:
// const a = new UnionRangeValidation().IsInRange("123");
[LOG]: false
// const a = new UnionRangeValidation().IsInRange("5");
[LOG]: true
交叉可以用于类、接口、泛型、基本类型。
// 将多个类型合并成一个类型
class Grid {
Width: number = 0;
Height: number = 0;
}
class Margin {
Top: number = 0;
Left: number = 0;
}
// 交叉
function ConsolidatedGrid(grid: Grid, margin: Margin) : Grid & Margin {
const consolidatedGrid = Object.assign({}, grid, margin);
return consolidatedGrid;
}
通过不改变原有的类,去增加功能。
对于要使用装饰器,请开启 experimentalDecorators
,设置为 true 。
原始类:
interface IDecoratorExample {
AnyoneCanRun(args: string): void;
AdminOnly(args: string): void;
}
class RoleCheck implements IDecoratorExample {
AnyoneCanRun(args: string): void {
console.log(args);
}
AdminOnly(args: string): void {
console.log(args);
}
}
输出结果:
// new RoleCheck().AnyoneCanRun("Jemmy as user can running.");
Jemmy as user can running.
// new RoleCheck().AdminOnly("Jemmy as Admin can running.")
Jemmy as Admin can running.
根据结果展示两个都能运行成功。
添加装饰器。
看到类似下面的这行代码,就表明这是一个装饰器。
function(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor)
函数说明:
function isInRole(role: string): boolean {
return user2.roles.some(r => r === role);
}
// 装饰器
function Role(role: string) {
return function(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
let originalMethod = descriptor.value;
descriptor.value = function() {
if (isInRole(role)) {
originalMethod.apply(this, arguments);
return ;
}
console.log(`${user2.user} is not in the ${role} role`);
}
return descriptor;
}
}
然后通过 @Role()
添加到需要装饰的函数上面。
@Role("user")
AnyoneCanRun(args: string): void {
console.log(args);
}
@Role("admin")
AdminOnly(args: string): void {
console.log(args);
}
测试结果:
// const user2 = {user: "Jemmy", roles: ["user"]}
// new RoleCheck().AnyoneCanRun("Jemmy as user can running.");
Jemmy as user can running
// new RoleCheck().AdminOnly("Jemmy as Admin can running.")
Jemmy is not in the admin role
可以给已存在构造器,添加额外的属性,而不是在原先的基础上修改。
必要的类型声明:
type Constructor<T = {}> = new (...args: any[]) => T;
根据情况去添加属性,这里以 Deleted 举例。
function RecordStatus<T extends Constructor >(base: T) {
return class extends base {
// 在这里写属性
Deleted: boolean = false;
}
}
// 进阶用法:
function RecordStatus<T extends Constructor >(base: T) {
return class extends base {
deleted: boolean = false;
get Deleted(): boolean {
return this.deleted;
}
Delete() : void {
this.deleted = true;
console.log("The record has been marked as deleted. ")
}
}
}
使用?
class Personn {
constructor(private firstName: string, private lastName: string) {}
}
// 创建一个新的构造器
const ActivePerson = RecordStatus(Person);
// 通过新的构造器去创建实例
let p1 = new ActivePerson("三", "张");
更多使用方式:可以嵌套。
其中 Timestame 和 RecordStatus 都是额外添加属性,它们嵌套顺序可以改变。
const ActivePerson = Timestamp(RecordStatus(Personn))
这一个知识点很简单,将类型转换成 T 去代替即可。
class Queue<T> {
private queue: T[] = [];
push(value: T) : void {
this.queue.push(value);
}
pop(): T | undefined {
return this.queue.shift();
}
get length() : number {
return this.queue.length;
}
}
输出结果:
// const q1 = new Queue();
// q1.push("1")
// q..push("2")
// q1.pop()
1
延时 time 毫秒。
function ExpensiveWebCall(time: number) : Promise<void> {
return new Promise((resolve, reject) => setTimeout(resolve, time));
}
使用?
console.log("正在处理...")
ExpensiveWebCall(3000).then(() => {
console.log("web service end")
}).catch(() => {
console.log("appear errors")
})