首页 > 其他分享 >【TS】TypeScript基础入门篇以及实践案例

【TS】TypeScript基础入门篇以及实践案例

时间:2024-09-23 09:14:49浏览次数:6  
标签:Direction TypeScript const string TS number 入门篇 let 类型

Array 和 Tuple

//最简单的方法是使用「类型 + 方括号」来表示数组:
let arrOfNumbers: number[] = [1, 2, 3, 4]
//数组的项中不允许出现其他的类型:
//数组的一些方法的参数也会根据数组在定义时约定的类型进行限制:
arrOfNumbers.push(3)
arrOfNumbers.push('abc') // 报错

// 元祖的表示和数组非常类似,只不过它将类型写在了里面 这就对每一项起到了限定的作用
let user: [string, number] = ['viking', 20]
//但是当我们写少一项 就会报错 同样写多一项也会有问题
user = ['molly', 20, true] // 报错

interface 接口

// 我们定义了一个接口 Person
interface Person {
    name: string;
    age: number;
  }
  // 接着定义了一个变量 viking,它的类型是 Person。这样,我们就约束了 viking 的形状必须和接口 Person 一致。
  let viking: Person = {
    name: 'viking',
    age: 20
  }
  
  //有时我们希望不要完全匹配一个形状,那么可以用可选属性:
  interface Person2 {
      name: string;
      age?: number;
  }
  let viking2: Person2 = {
      name: 'Viking'
  }
  
  //接下来还有只读属性,有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
  
  interface Person3 {
    readonly id: number;
    name: string;
    age?: number;
  }

  let viking3: Person3 = {
    id: 89757,
    name: 'Viking'
}

  viking3.id = 9527 // 报错
  

Function 函数

// 第一个例子,约定输入,约定输出
function add(x: number, y: number): number {
    return x + y;
}

// 可选参数
function add2(x: number, y: number, z?: number): number {
    if(typeof z === 'number'){
        return x + y + z;
    } else {
        return x + y;
    }
}

// 函数本身的类型
const add3: (x: number,y: number, z?: number) => number = add2;

// interface描述函数类型
const sum = (x: number, y: number) => {
    return x + y;
}

interface ISum {
    (x: number, y: number): number;
}

const sum2: ISum = sum;

类型推论、联合类型和类型断言

类型推论

地址:https://www.typescriptlang.org/docs/handbook/type-inference.html

let x = 3;

自动推导出x的类型为number类型。

联合类型 union types

// 我们只需要用中竖线来分割两个
let numberOrString: number | string 
// 当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
numberOrString.length // 报错
numberOrString.toString()

类型断言 types assertions

// 这里我们可以用 as 关键字,告诉typescript 编译器,你没法判断我的代码,但是我本人很清楚,这里我就把它看作是一个 string,你可以给他用 string 的方法。
function getLength(input: string | number): number {
    const str = input as string
    if (str.length) {
      return str.length
    } else {
      const number = input as number
      return number.toString().length
    }
}

类型守卫 types guard

  // typescript 在不同的条件分支里面,智能的缩小了范围,这样我们代码出错的几率就大大的降低了。
function getLength2(input: string | number): number {
    if (typeof input === 'string') {
      return input.length
    } else {
      return input.toString().length
    }
  }

枚举 Enums

// 数字枚举,一个数字枚举可以用 enum 这个关键词来定义,我们定义一系列的方向,然后这里面的值,枚举成员会被赋值为从 0 开始递增的数字,
enum Direction {
    Up,
    Down,
    Left,
    Right,
  }
  console.log(Direction.Up) // 0
  
  // 还有一个神奇的点是这个枚举还做了反向映射
  console.log(Direction[0]) // 'Up'
  

字符串枚举:

  // 字符串枚举
 enum Direction {
   Up = 'UP',
   Down = 'DOWN',
   Left = 'LEFT',
   Right = 'RIGHT',
 }
 const value = 'UP'
 if (value === Direction.Up) {
   console.log('go up!')
 }

对应上面的代码,我们编译后的JS:

var Direction;
(function (Direction) {
    Direction["Up"] = "UP";
    Direction["Down"] = "DOWN";
    Direction["Left"] = "LEFT";
    Direction["Right"] = "RIGHT";
})(Direction || (Direction = {}));
var value = 'UP';
if (value === Direction.Up) {
    console.log('go up!');
}

如果我们把它改成常量枚举,可以提高性能,代码如下:

  const enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT',
  }
  const value = 'UP'
  if (value === Direction.Up) {
    console.log('go up!')
  }

编译成JS后的代码:

var value = 'UP';
if (value === "UP" /* Direction.Up */) {
    console.log('go up!');
}

泛型 Generics

基础介绍

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

  function echo<T>(arg: T): T {
    return arg
  }
  const result = echo(123)
  
  // 泛型也可以传入多个值
  function swap<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]]
  }
  
  const result2 = swap(['string', 123])

泛型约束

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法

 function echoWithArr<T>(arg: T): T {
    console.log(arg.length)
    return arg
  }
  
  

上例中,泛型 T 不一定包含属性 length,我们可以给他传入任意类型,当然有些不包括 length 属性,那样就会报错,那么我就需要使用泛型约束来解决,如下示例:

  interface IWithLength {
    length: number;
  }
  function echoWithLength<T extends IWithLength>(arg: T): T {
    console.log(arg.length)
    return arg
  }
  
echoWithLength('str')
const result3 = echoWithLength({length: 10})
const result4 = echoWithLength([1, 2, 3])

泛型与类和接口的应用

如下示例:

class Queue {
    private data: any[] = []
    push(item) {
        return this.data.push(item)
    }
    pop() {
        return this.data.shift();
    }
}

const queue = new Queue();
queue.push("1");

const poped = queue.pop();
if(poped) {
    const res = poped.toFixed();
    console.log(res);
}

当我们跟queue实例添加了一个1进去,然后再拿出来,把拿出来的这个内容调用toFixed方法,当这个数是数字,当然不会报错,如果是上面的字符串,那么在运行的时候就会报错,如下所示:

var res = poped.toFixed();
                   ^

TypeError: poped.toFixed is not a function

使用泛型调整后的代码:

class Queue<T> {
    private data: T[] = []
    push(item: T) {
        return this.data.push(item)
    }
    pop(): T {
        return this.data.shift();
    }
}

const queue = new Queue<number>();
queue.push("1"); // 这样这儿就会报错了

const poped = queue.pop();
if(poped) {
    const res = poped.toFixed();
    console.log(res);
}

泛型和interface示例:

interface keyPair<T,U> {
    key: T;
    value: U;
}

let kp1: keyPair<number,string> = {key: 1, value: 'str'};
let kp2: keyPair<string,number> = {key: 'str', value: 1};

类型别名和交叉类型

let sum: (x: number, y: number) => number = function(x: number, y: number):number {
    return x + y
}

const result = sum(1,2) 
type PlusType = (x: number, y: number) => number
let sum2: PlusType

// 支持联合类型
type StrOrNumber = string | number
let result2: StrOrNumber = '123'
result2 = 123

// 字符串字面量
type Directions = 'Up' | 'Down' | 'Left' | 'Right'
let toWhere: Directions = 'Up'

声明文件

官方声明文件库:https://github.com/DefinitelyTyped/DefinitelyTyped/

例如,我们声明一个axios函数,它有get和post两个方法。

interface IAxios {
  get: (url: string) => string;
  post: (url: string, data: any) => string;
}

declare const axios: IAxios;

使用方式:

axios.get('url地址')
axios.post('url地址',{name: 'zhangsan'})

类型声明示例

如下示例,我们要实现如下这样的调用方式:

calculator('minus', [1, 2]);
calculator('plus', [1, 2]);

calculator.minus([1, 2]);
calculator.plus([1, 2]);

我们要实现calculator('minus', [1, 2]) 这样的形式,就相当于我们调用一个函数,有两个参数,我们可以借助类型别名来实现。

如下声明,即实现了calculator('minus', [1, 2])的声明调用:

type IOperator = 'plus' | 'minus';
type ICalculator = (operator: IOperator, numbers: number[]) => number;
declare const calculator: ICalculator;

那我们怎样才能实现在一个函数中添加两个属性,那么我们可以使用接口的定义来调整声明代码:

type IOperator = 'plus' | 'minus';
// type ICalculator = (operator: IOperator, numbers: number[]) => number;
interface ICalculator {
  (operator: IOperator, numbers: number[]): number;
  plus: (numbers: number[]) => number;
  minus: (numbers: number[]) => number;
}
declare const calculator: ICalculator;

这样我们再进行下面的调用就不回报错了:

calculator('minus', [1, 2]);
calculator('plus', [1, 2]);

calculator.minus([1, 2]);
calculator.plus([1, 2]);

内置类型

const a: Array<number> = [1,2,3]
// 大家可以看到这个类型,不同的文件中有多处定义,但是它们都是 内部定义的一部分,然后根据不同的版本或者功能合并在了一起,一个interface 或者 类多次定义会合并在一起。这些文件一般都是以 lib 开头,以 d.ts 结尾,告诉大家,我是一个内置对象类型欧
const date: Date = new Date()
const reg = /abc/
// 我们还可以使用一些 build in object,内置对象,比如 Math 与其他全局对象不同的是,Math 不是一个构造器。Math 的所有属性与方法都是静态的。

Math.pow(2,2)

// DOM 和 BOM 标准对象
// document 对象,返回的是一个 HTMLElement
let body: HTMLElement = document.body
// document 上面的query 方法,返回的是一个 nodeList 类型
let allLis = document.querySelectorAll('li')

//当然添加事件也是很重要的一部分,document 上面有 addEventListener 方法,注意这个回调函数,因为类型推断,这里面的 e 事件对象也自动获得了类型,这里是个 mouseEvent 类型,因为点击是一个鼠标事件,现在我们可以方便的使用 e 上面的方法和属性。
document.addEventListener('click', (e) => {
  e.preventDefault()
})

Typescript 还提供了一些功能性,帮助性的类型,这些类型,大家在 js 的世界是看不到的,这些类型叫做 utility types,提供一些简洁明快而且非常方便的功能。

// partial,它可以把传入的类型都变成可选
interface IPerson {
  name: string
  age: number
}

let viking: IPerson = { name: 'viking', age: 20 }
type IPartial = Partial<IPerson>
let viking2: IPartial = { }

// Omit,它返回的类型可以忽略传入类型的某个属性

type IOmit = Omit<IPerson, 'name'>
let viking3: IOmit = { age: 20 }

配置文件

配置文件官网地址:https://www.typescriptlang.org/tsconfig/

{
  "files": ["test.ts", "test2.d.ts"],
  "compilerOptions": {
    "outDir": "./output",
    "module": "ESNext",
    "target":"ES5",
    "declaration": true
  }
}

标签:Direction,TypeScript,const,string,TS,number,入门篇,let,类型
From: https://www.cnblogs.com/moqiutao/p/18426310

相关文章

  • 2024/09/22:TypeScript 学习笔记二
    1、类型注解在TypeScript中,可以使用类型注解来明确标识类型。如:constgreeting:string='helloworld' 2、类型检查静态类型检查:在程序编译时进行——(两种静态类型检查模式:非严格类型检查【默认方式】;严格类型检查)动态类型检查:在程序运行时进行3、TypeScri......
  • 从规范到实现解读Windows平台如何播放RTSP流
    RTSP播放器应用场景RTSP播放器在视频监控、远程视频会议、网络电视、实时流媒体传输、协同操控相关的智能设备、教育培训以及企业内部通讯与协作等多个领域都有着广泛的应用场景。1.视频监控RTSP直播播放器在视频监控系统中扮演着重要角色。通过RTSP协议,播放器可以实时接收来自监......
  • 知其然知其所以然-以视频播放器为例解读RTSP协议的作用
    技术背景好多开发者在用大牛直播SDK的RTSP播放器模块的时候,希望知其然知其所以然,以便跟甲方沟通的时候,底气更足。本文从RTSPsession建立开始,详细解读RTSP播放器的实现原理。RTSP播放器应用场景RTSP播放器具有以下一些主要的使用场景:一、监控领域视频监控系统:在企业、学校、公共场......
  • 【TS】加深TS理解的开发实战示例代码
    TS接口开发实战:基于类类型接口设计实现日期时间应用interfaceITimeDate{curTime:Date;setTime(cur:Date):void;getTime():Date;}classCTimeimplementsITimeDate{curTime:Date;constructor(cur:Date){this.curTime=cur;......
  • 代码实践!如何使用CAMEL Agents构建 GraphRAG ?
    关注公众号:青稞AI,第一时间学习最新AI技术......
  • [机器人仿真]WEBOTS中创建轮腿机器人模型-并联闭环机构的创建和使用
    想着做个轮腿的机器人玩玩,但是如果光用PID做算法,对于轮子加腿的结构似乎效果并不好,为了实现轮腿本身能够飞坡在一定高度下能够跳跃,我想着上个仿真模型来调试和学习LQR算法机器人仿真的软件似乎挺多,我查到比较常用的有ROS套件的一个,还有就是webots本着界面简单,开源(还有校园网方便......
  • [CVPR2024]DeiT-LT Distillation Strikes Back for Vision Transformer Training on L
    在长尾数据集上,本文引入强增强(文中也称为OOD)实现对DeiT的知识蒸馏的改进,实现尾部类分类性能的提升。动机ViT相较于CNN缺少归纳偏置,如局部性(一个像素与周围的区域关系更紧密)、平移不变性(图像的主体在图像的任意位置都应该一样重要)。因此需要大型数据集进行预训练。长尾数据学习......
  • [Mysql]基础入门篇_关于数据库的简介_初识DQL语句
    @[TOC]文章目录何为数据库数据库类型数据库管理系统(本博主使用的是Mysql数据库)何为SQL准备工作及select查询操作的简单使用何为数据库数据库是一个有组织的数据集合,允许高效存储、管理和检索信息。它通过结构化的方式存储数据,通常使用数据库管理系统(DBMS)来执行操作,如......
  • 开放食物营养库python SDK套件:openfoodfacts-python
    官网源码:GitHub-openfoodfacts/openfoodfacts-python:......
  • Android轻量级RTSP服务使用场景分析和设计探讨
    技术背景好多开发者,对我们Android平台轻量级RTSP服务模块有些陌生,不知道这个模块具体适用于怎样的场景,有什么优缺点,实际上,我们的Android平台轻量级RTSP服务模块更适用于内网环境下、对并发要求不高的场景,实现低成本、低延迟的音视频实时传输。本文就上述问题,做个技术探讨,先说......