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

文章目录

    • Array 和 Tuple
    • interface 接口
    • Function 函数
    • 类型推论、联合类型和类型断言
      • 类型推论
      • 联合类型 union types
      • 类型断言 types assertions
      • 类型守卫 types guard
    • 枚举 Enums
    • 泛型 Generics
      • 基础介绍
      • 泛型约束
      • 泛型与类和接口的应用
    • 类型别名和交叉类型
    • 声明文件
      • 类型声明示例
      • 内置类型
    • 配置文件

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 stringif (str.length) {return str.length} else {const number = input as numberreturn 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: stringage: 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}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148525.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MemFire Cloud,让Coding更丝滑

作为一个开发者&#xff0c;每天与代码打交道的你&#xff0c;是否总觉得开发流程太繁琐&#xff1f;后端搭建复杂&#xff0c;接口设计麻烦&#xff0c;甚至连数据库配置都让你心烦不已。别担心&#xff0c;今天要给你推荐一个真正能让开发变得丝滑的工具——MemFire Cloud。如…

【Python数据分析】pandas apply自定义函数+分组操作+分析案例

文章目录 1.apply()1.1函数 操作series对象1.2 apply()函数 > 操作DataFrame对象1.3 向量化函数1.4 apply()函数的案例-泰坦尼克号数据集1.5 apply()函数 结合 lambda表达式使用. 2. 分组操作2.1 分组 聚合操作2.2 分组 转换2.3 分组 过滤2.4 DataFrameGroupby df的分组对…

Java面试题大全(全网最全,持续更新)中级(2)

1. 集合与泛型 1.1. 什么是泛型&#xff1f;泛型的优势是什么&#xff1f; 泛型允许类、接口和方法在定义时不指定具体的类型&#xff0c;在使用时再指定类型。优势&#xff1a; 提高代码复用性。提供类型安全&#xff0c;避免强制类型转换带来的 ClassCastException。 pub…

word批量裁剪图片,并调整图片大小,不锁定纵横比

在word中有若干图片待处理&#xff0c;裁剪出指定内容&#xff0c;调整成指定大小。如下是待处理的图片&#xff1a; 这时&#xff0c;选择视图&#xff0c;选择宏&#xff0c;查看宏 选择创建宏 添加cut_picture代码如下&#xff0c;其中上、下、左、右裁剪的橡塑尺寸根据自己…

李飞飞创业公司World Labs:引领AI新方向的“大世界模型”

引言 随着人工智能的不断进步&#xff0c;AI领域涌现了许多新兴技术和研究方向。在这其中&#xff0c;李飞飞创办的World Labs凭借其独特的“空间智能”和“大世界模型”&#xff08;Large World Model, LWM&#xff09;理念&#xff0c;迅速成为焦点。尤其是在获得了2.3亿美元…

系统架构设计师教程 第10章 10.5 软件架构演化评估方法笔记

10.5 软件架构演化评估方法 ★★★☆☆ 10.5.1 演化过程已知的评估 目的在于通过对架构演化过程进行度量&#xff0c;比较架构内部结构上的差异以及由此导致的外部质量属性上的变化&#xff0c;对该演化过程中相关质量属性进行评估。 1.评估流程 架构演化评估的基本思路是将架…

IDEA快速查看类中有那些方法的快捷键

IDEA快速查看类中有那些方法的快捷键 1.显示类结构弹出窗口 你可以使用以下快捷键来快速查看当前类的方法和成员&#xff1a; Windows/Linux: Ctrl F12 macOS: Option F12 或 ⌥ F12 这会打开一个弹出窗口&#xff0c;显示当前类的结构&#xff0c;包括方法、字段、构造函…

派可数据:解锁数据潜力,驱动业务价值新增长

前 言 当前&#xff0c;企业数字化转型经过初始探索阶段&#xff0c;各行各业进入高速发展百花齐放的创新应用新阶段。创新应用阶段的核心是企业应用先进的数字技术和工具&#xff0c;对企业多年在全领域积累的各类数据&#xff0c;包括财务、业务、生产、设计、设备、工艺等结…

车载应用的多功能需求与公安、金融等行业的应用特点

随着科技的快速发展&#xff0c;车载应用的功能需求也日益多样化。除了基本的视频监控功能外&#xff0c;现代车载应用还需满足一系列高级功能&#xff0c;如无线网络视频监控、GPS卫星定位、车辆调度、语音报站、行驶信息记录以及多媒体娱乐广告播放等。这些功能在公安、金融等…

Vue 实战教程:从 0 到 1 手把手打造新手友好的聊天应用,附完整开源代码,快速上手前端开发!(包含发送消息、发送表情包、发送文件、下载文件、截图等功能)

b站视频演示效果&#xff1a; 效果图&#xff1a; 完整代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8" /><title>简单聊天功能示例</title><!-- 引入 Vue.js&#xff08;通过 …

深度优先搜索算法及其matlab程序详解

#################本文为学习《图论算法及其MATLAB实现》的学习笔记################# 深度优先搜索算法(DepthFirst Search),简记DFS算法,是图论中的首要算法,其思想方法渗透到图论中的许多算法之中,尤其是DFS算法在求生成树、割点、块和平面图嵌入算法中起着极为关键的作用。…

开源ids snort (windows版)

Snort-IPS-on-Windows-main资源-CSDN文库 GitHub - eldoktor1/Snort-IPS-on-Windows: A comprehensive guide to installing and configuring Snort IPS on Windows, ensuring robust network security 解压后安装 npcap-1.75.exe Snort_2_9_20_Installer.x64.exe 安装后cm…

MiniMind环境搭建训练推理测试

引子 写了那么多篇大模型环境搭建推理部署的blog&#xff0c;如果没记错有几篇就是因为GPU资源hold不住&#xff0c;没有无法得到最终结果的&#xff08;智谱AI GLM-4V-9B视觉大模型环境搭建&推理-CSDN博客&#xff09;。我个人一直觉得大模型发展最终还是要走向端侧&…

8591 计算next值

### 思路 1. **录入字符串**&#xff1a;读取用户输入的字符串个数 n&#xff0c;然后逐个读取每个字符串。 2. **计算NEXT值**&#xff1a;对于每个字符串&#xff0c;计算其NEXT数组。 3. **输出NEXT值**&#xff1a;输出每个字符串对应的NEXT数组。 ### 伪代码 function g…

DevExpress WPF中文教程:如何解决行焦点、选择的常见问题?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

环境部署-环境变量

环境部署-环境变量 1、python设置查找环境变量2、linux设置设置查找环境变量 仅个人笔记使用&#xff0c;感谢点赞关注 1、python设置查找环境变量 python设置环境变量 import os os.environ["PYTHONPATH"] "/path/to/library"python获取环境变量 MYS…

AI时代最好的编程语言应该选择谁?

在AI的时代&#xff0c;编程语言的选择对就业机会和薪资水平有着至关重要的影响。C和Python被认为是两个极端的代表语言&#xff0c;分别适用于不同的技术需求和开发场景。然而&#xff0c;选择最有价值的编程语言&#xff0c;不仅要考虑其技术特性&#xff0c;还需要综合考虑行…

【数据结构】你真的了解哈希表吗?看完你会对数据结构——哈希表, 会有更深更全面的认识 (理论篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

实例讲解电动汽车VCU故障分类、故障码发送策略及Simulink建模方法

汽车作为一个上万零部件组成的工业品&#xff0c;从设计研发到试制调试再到路试可靠性测试再到车辆批量生产&#xff0c;要经历一个相当长的周期。在设计研发阶段&#xff0c;从设计方案与原理上尽量减少故障出现的可能&#xff0c;在试制调试阶段&#xff0c;通过全面的调试测…

车间设备巡检的意义与设备巡检系统的选择之道

在现代工业生产中&#xff0c;车间设备是企业的核心资产&#xff0c;其稳定运行直接关系到企业的生产效率、产品质量以及经济效益。而车间设备巡检作为设备管理的重要环节&#xff0c;具有不可忽视的重要性。 一、车间设备巡检的重要性 车间设备在长时间、高强度的运行过程中&…