首页 > 其他分享 >【TS】加深TS理解的开发实战示例代码

【TS】加深TS理解的开发实战示例代码

时间:2024-09-22 21:38:04浏览次数:1  
标签:实战 console log 示例 TS echo let arg number

TS接口

开发实战:基于类类型接口设计实现日期时间应用

interface ITimeDate {
    curTime: Date;
    setTime(cur: Date): void;
    getTime(): Date;
}

class CTime implements ITimeDate {
    curTime: Date;
    constructor(cur: Date) {
        this.curTime = cur;
    }

    setTime(cur: Date): void {
        this.curTime = cur;
    }

    getTime(): Date {
        let curTime: Date;
        if(this.curTime) {
            curTime = this.curTime;
        } else {
            curTime = new Date();
        }
        return curTime;
    }
}

let ct: CTime = new CTime(new Date());
console.log(ct.getTime());

let newTime: Date = new Date("2021/10/21 00:00:00");
ct.setTime(newTime);
console.log("New time is: " + ct.getTime());

开发实战:基于单接口继承设计实现计算周长的应用

interface IShape {
  girth: number;
}
interface ISqure extends IShape {
  shapeType: string;
  getGirth(): number;
}

class CSquare implements ISqure {
  shapeType: string;
  girth: number;

  constructor(sideLength: number) {
    this.shapeType = 'Square';
    this.girth = sideLength * 4;
  }

  getGirth(): number {
    return this.girth;
  }
}

let cs: CSquare = new CSquare(6);
console.log(
  cs.shapeType + 'sideLength is 6, then girth is ' + cs.getGirth() + '.'
);

声明了一个表示几何图形的抽象接口IShape,其中包括一个表示图形周长的属性girth.

同时声明了一个继承自抽象接口IShape的接口ISquare,用来描述正方形。

最后定义了一个实现接口ISquare的类CSquare。

开发实战:基于多接口继承设计实现计算周长和面积的应用

前一个应用是通过单接口继承实现的,其实TypeScript多接口继承功能更常用。

我们对上述示例进行改进,通过TypeScript多接口继承设计实现同时计算正方形周长和面积的应用。

interface IGirth {
    girth: number;
}
interface IArea {
    area: number;
}

interface ISquareB extends IGirth, IArea {
    shapeType: string;
    getGirth(): number;
    getArea(): number;
}
class CSquareB implements ISquareB {
    shapeType: string;
    girth: number;
    area: number;
    constructor(sideLength: number) {
        this.shapeType = "Square";
        this.girth = 4 * sideLength;
        this.area = sideLength * sideLength;
    }
    getGirth(): number {
        return this.girth;
    }
    getArea(): number {
        return this.area;
    }
}

let csB: CSquareB = new CSquareB(6);
console.log(csB.shapeType + " sideLength is 6, then girth is " + csB.getGirth() + ".");
console.log(csB.shapeType + " sideLength is 6, then area is " + csB.getArea() + "." );

开发实战:基于混合类型接口设计实现计数器应用

下面通过TypeScript混合类型接口设计实现一个具有计数器(初始化、累加、调整步长和重置)功能的应用。

interface ICounter {
    (s: string): void;
    current: number;
    interval: number;
    count(): void;
    setInterval(i: number): void;
    reset(): void;
}

function getCounter(): ICounter {
    let counter = <ICounter>function(s: string): void {
        console.log(s);
    }

    // init counter
    counter.current = 0;
    counter.interval = 1;

    counter.count = function() {
        counter.current += counter.interval;
        console.log('Now current count is: ' + counter.current + '.');
    }

    counter.setInterval = function(i: number) {
        counter.interval = i;
        console.log('Now interval changes to:' + counter.interval + '.');
    }

    counter.reset = function() {
        counter.current = 0;
        console.log('Now current count is reset to 0.');
    }

    return counter;
}

let c = getCounter();
console.log('counter typescript app:');
c.count();
c.setInterval(5);
c.count();
c.reset();
c.setInterval(1);
c.count();

最终结果:

counter typescript app:
Now current count is: 1.
Now interval changes to:5.
Now current count is: 6.
Now current count is reset to 0.
Now interval changes to:1.

ICounter 接口定义了一个函数类型和一些属性和方法:

interface ICounter {
    (s: string): void; // 这是一个函数类型
    current: number;   // 这是一个属性
    interval: number;  // 这是一个属性
    count(): void;     // 这是一个方法
    setInterval(i: number): void; // 这是一个方法
    reset(): void;     // 这是一个方法
}

通过类型断言 ,我们确保 counter 变量不仅包含一个函数,还包含 current、interval 属性以及 count、setInterval 和 reset 方法。这样,TypeScript 编译器就会检查这些属性和方法是否都被正确地初始化和实现。

说明如下代码意思:

let counter = <ICounter>function(s: string): void {
    console.log(s);
}
  • 定义一个匿名函数 function(s: string): void { console.log(s); }。
  • 使用类型断言 将这个匿名函数断言为 ICounter 类型。

在 TypeScript 中,类型断言有两种语法形式:

  • 使用尖括号 ,例如
  • 使用 as 关键字,例如 as ICounter。

TypeScript类

开发实战:设计实现存取器应用

在TypeScript类语法中,支持通过getters/setters存取器方式来执行对类成员的访问操作,这种方式能帮助开发人员有效地控制对类成员的访问。在TypeScript类中,设计存取器需要使用get(获取)和set(存储)修饰符来定义。

class CGetSet {
    private _name: string;

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

    get Name(): string {
        return this._name;
    }

    set Name(theName: string) {
        theName = theName.trim();
        if(theName && theName.length) {
            this._name = theName;
        } else {
            console.log('error:theName is empty.');
        }
    } 
}

let gs = new CGetSet('set&get');
console.log(gs.Name); // set&get
gs.Name = 'reset set&get';
console.log(gs.Name); // reset set&get

TypeScript 函数

开发实战:箭头函数与this关键字应用

let userInfo = {
    uname: 'zhangsan',
    printInfo() {
        return function () {
            return {name: this.uname}
        }
    }
}

const ui = userInfo.printInfo();
console.log(ui().name)

上面代码中this会报错,编译信息提示this关键字的类型为Any的错误。

方式一,用箭头函数调整:

let userInfo = {
    uname: 'zhangsan',
    printInfo() {
        return () => {
            return {name: this.uname}
        }
    }
}

const ui = userInfo.printInfo();
console.log(ui().name)

方式二,使用 that 或 self 变量:

let userInfo = {
    uname: 'zhangsan',
    printInfo() {
        const self = this;
        return function () {
            return {name: self.uname}
        }
    }
}

方式三:使用 apply 或 call 方法

可以在调用嵌套函数时使用 apply 或 call 方法来显式设置 this。

let userInfo = {
    uname: 'zhangsan',
    printInfo() {
        return function (this: typeof userInfo) {
            return {name: this.uname}
        }
    }
}

const ui = userInfo.printInfo();
console.log(ui.apply(userInfo).name)

TypeScript 泛型

开发实战:泛型变量应用

function echoVar<T>(arg: Array<T>): Array<T> {
    console.log('arg length:' + arg.length)
    return arg;
}

console.log(echoVar([1, 2]))
console.log(echoVar(['a', 'b']))

上述代码定义了一个泛型函数echoVar,参数arg定义为类型<T>的数组形式Array<T>。

开发实战:泛型类型应用

使用泛型类型定义泛型函数的应用

function echo_type<T>(arg: T): T {
    return arg;
}

let arrow_echo_type: <T>(arg:T) => T = echo_type;

console.log(arrow_echo_type("Hello")); // Hello

上述代码,通过泛型类型<T>(arg:T)定义了一个泛型函数变量arrow_echo_type,并指定为泛型函数echo_type。

另外,我们可以使用具有调用签名的对象字面量来定义泛型函数:

function echo_type<T>(arg: T): T {
    return arg;
}

let liter_echo_type: {<T>(arg:T):T} = echo_type;
console.log(liter_echo_type("Hello")); // Hello

开发实战:泛型接口应用

我们可以将对象字面量“{<T>(arg:T):T}”单独封装为一个接口形式。

interface IGenericsEcho {
    <T>(arg: T): T;
}

function fn_echo_generics<T>(arg: T): T {
    return arg;
}

let echo_gen: IGenericsEcho = fn_echo_generics;
console.log(echo_gen('define generics func by interface'));

上述代码,声明了一个接口IGenericsEcho,通过对象字面量“<T>(arg:T):T”定义了泛型函数的类型。

通过泛型接口IGenericsEcho和泛型函数fn_echo_generics定义了一个函数变量echo_gen。

进一步在接口声明中直接加上类型<T>,写成真正的泛型接口形式。上述代码调整为如下:

interface IGenericsEcho<T> {
   (arg: T): T;
}

function fn_echo_generics<T>(arg: T): T {
    return arg;
}

let echo_gen_str: IGenericsEcho<string> = fn_echo_generics;
let echo_gen_num: IGenericsEcho<number> = fn_echo_generics;
console.log(echo_gen_str('define generics func by interface'));
console.log(echo_gen_num(123));

上面代码声明了一个泛型接口IGenericsEcho<T>,接口类型为“(arg:T):T”。

我们在使用该泛型接口定义函数变量echo_gen_num和echo_gen_str时,需要指定具体类型。

开发实战:泛型类应用

class EchoGenerics<T> {
    private _m_arg: T;
    constructor(arg: T) {
        this._m_arg = arg;
    }

    public echo(): void {
       console.log(this._m_arg)
    }
}

let g_echo_str = new EchoGenerics<string>("Hello World");
g_echo_str.echo();
let g_echo_num = new EchoGenerics<number>(123);
g_echo_num.echo();

TypeScript 高级类型

类型别名

在类型别名中使用泛型来模拟接口功能的应用。

type StrNum = string | number;
type aliasGeneric<T> = {
    x: T;
    y: T;
}

function getXY(ag: aliasGeneric<StrNum>) {
    if(typeof ag.x === 'number' && typeof ag.y === 'number') {
        console.log(ag.x + ag.y)
    }
    else if(typeof ag.x === 'string' && typeof ag.y === 'string') {
        console.log(`${ag.x} ${ag.y}`)
    }
    else {
        console.log('other alias-type generic')
    }
}

let agStr: aliasGeneric<string> = {
    x: 'a',
    y: 'b'
}
getXY(agStr);

let agNum: aliasGeneric<number> = {
    x: 1,
    y: 2
}
getXY(agNum);

映射类型

如下示例,通过映射类型方式将原接口IPerson的属性转换为只读属性:

interface IPerson {
    name: string;
    age: number;
}

type TReadyOnly<T> = {
    readonly [p in keyof T]: T[p];
}

type ReadyOnlyPerson = TReadyOnly<IPerson>;

通过映射类型方式将原接口IPerson的属性转换为可选属性:

interface IPerson {
    name: string;
    age: number;
}

type TOptional<T> = {
    [p in keyof T]?: T[p];
}

type OptionalPerson = TOptional<IPerson>;

标签:实战,console,log,示例,TS,echo,let,arg,number
From: https://www.cnblogs.com/moqiutao/p/18425925

相关文章

  • 代码实践!如何使用CAMEL Agents构建 GraphRAG ?
    关注公众号:青稞AI,第一时间学习最新AI技术......
  • [机器人仿真]WEBOTS中创建轮腿机器人模型-并联闭环机构的创建和使用
    想着做个轮腿的机器人玩玩,但是如果光用PID做算法,对于轮子加腿的结构似乎效果并不好,为了实现轮腿本身能够飞坡在一定高度下能够跳跃,我想着上个仿真模型来调试和学习LQR算法机器人仿真的软件似乎挺多,我查到比较常用的有ROS套件的一个,还有就是webots本着界面简单,开源(还有校园网方便......
  • 影刀RPA实战:网页爬虫之药品数据
    1实战目标这次给大家带来的实战示例是采集中国医药信息平台上的药品数据,主要获取药品名称,介绍,药品类型,处方类型,医保类型,参考价格,药品成分,性状,适应病症,用法用量等。我们依然使用excel将这些需要的数据字段展示出来需要准备的影刀知识:网页元素操作流程判断与循环excel操作......
  • [CVPR2024]DeiT-LT Distillation Strikes Back for Vision Transformer Training on L
    在长尾数据集上,本文引入强增强(文中也称为OOD)实现对DeiT的知识蒸馏的改进,实现尾部类分类性能的提升。动机ViT相较于CNN缺少归纳偏置,如局部性(一个像素与周围的区域关系更紧密)、平移不变性(图像的主体在图像的任意位置都应该一样重要)。因此需要大型数据集进行预训练。长尾数据学习......
  • appium+python自动化代码示例
    fromselenium.webdriver.common.byimportByimporttime#设置Appium连接参数caps={"platformName":"Android","platformVersion":"7.1.2",#根据夜神模拟器的Android版本进行修改"deviceName":"127.0.0.......
  • 探索 Kubernetes 服务网格:Istio 实战指南
    ......
  • 开放食物营养库python SDK套件:openfoodfacts-python
    官网源码:GitHub-openfoodfacts/openfoodfacts-python:......
  • Redis从基础到实战总结+Redisson分布式锁小结
    一、NoSQL和RDBMS的区别传统的rdbms结构化组织SQL数据和关系都存储在单独的表中操作语言是数据库定义语言严格的一致性基础的事务NoSql不仅仅是数据没有固定的语言键值对存储,列存储、文档存储、图形数据库最终一致性cpa定理和base高性能,高可用,高可扩二、NoSql的四大分类......
  • 强化学习基础:主要算法框架与Python实现示例
    创作不易,您的打赏、关注、点赞、收藏和转发是我坚持下去的动力!强化学习(ReinforcementLearning,RL)是一种通过与环境交互来学习策略的机器学习方法。RL主要包含以下几个关键组件:状态(State)、动作(Action)、奖励(Reward)、策略(Policy)和价值函数(ValueFunction)。常见的强化学习主流......
  • 小波变换及示例
    在二维Haar小波中,输入数据分解为低频和高频分量的计算公式源自Haar小波的特性,以及对输入矩阵的行和列进行逐步分解的方式。###Haar小波变换的基本思想Haar小波是最简单的小波变换,它基于二进制分解。对于二维数据(如图像),通常先对行进行一维变换,然后对列进行一维变换,得到四......