🚀🚀🚀Typescript通关秘籍(一)🔥🔥🔥

前言

截止到小编写这篇的时候,Typescript 已经发布到 5.3.2 版本了,好像现在写这文章是有点"迟"了?😰

不过,无所谓,就当一个总结,也方便以后随时能查阅叭。

接下来,咱们开始愉快的学习之旅,冲冲冲。👻

简介

开头一问:"What is TypeScript?"

一句话总结:"TypeScript 是 JavaScript 的一个超集。"

直接放上官网地址:传送门

那个谁(行业中的名人)曾说:"Javascript 早期拼命把 Type 从 Javscript 中移除,现在却又努力要把它加回来。" 😗😗😗

这里,咱们就不具体追本溯源了,这不重要,我们只要关心其中利弊如何即可。

优点

  • 增加代码的可读性和可维护性,比如接口请求参数与接口响应数据,我们能直接通过代码就能知道需要的数据类型。

  • 在编译阶段就能发现大部分错误,更好的避免了线上bug。

  • 增强了编译器的补全、接口提示功能。

缺点

  • 学习成本:有一定的学习成本,接口、泛型、枚举、类等新型概念需要去学习。

  • 开发成本:开发前期会增加一些开发成本,但后期维护就会相对比较简单。

  • 时间成本:TS的编译需要时间,开发启动和打包时间成本会增加。

  • 风险成本:一些JS库需要做兼容,需要手动提供声明文件。

环境配置

由于 TS 代码无法像 JS 一样直接在浏览器中运行,也不能在 Node 环境中运行,所以,要执行 TS 需要一个转译的过程,将其转成 JS 才能被执行。

因此,在正式学习 TS 之前,你还需要先配置 TS 的环境。

以下,小编提供了三种方式让你能执行 TS 代码,就看你钟爱哪种了。😉

tsc

全局安装 TS

javascript 复制代码
npm install -g typescript

(作为一名前端程序猿,你还没安装❓❓❓相信大部分前端小伙伴应该都是安装了的)

检查一下安装是否成功:

javascript 复制代码
tsc -v

能正常看到版本号就说明安装成功了。

接下来,我们开始来编译我们第一个 .ts 文件。

创建 test.ts 文件:

javascript 复制代码
const articleName: string = '橙某人';
console.log(articleName);

直接编译命令:

javascript 复制代码
tsc test.ts

执行后,将会生成一个 .js 文件,并且 TS 代码也会被编译成普通的 ES5 代码了。

tsc 命令后面可以接受一些参数,如:

lua 复制代码
// 编译 src 目录的所有 .ts 文件
tsc src/*.ts

// 指定编译配置文件
tsc --project tsconfig.production.json

// 只生成类型声明文件,不编译出 JS 文件
tsc index.js --declaration --emitDeclarationOnly

// 多个 TS 文件编译成单个 JS 文件
tsc app.ts util.ts --target esnext --outfile index.js

更多参数信息可以查阅官网:传送门

阮一峰大神的中文版解释:传送门

在使用 tsc 命令时,后面如果不带任何参数,则会获取读取 tsconfig.json 文件的配置信息。如果没有提供该文件,则会抛出错误,无法编译。

tsc 的命令行参数,大部分与 tsconfig.json 文件的属性一一对应。

ts-node

tsc 虽然能帮我们将 TS 转成 JS,但有时开发测试,这种方式还是很不方便。😐

ts-node:能帮我们在 Node 环境中直接执行 .ts 文件。

全局安装 ts-node

javascript 复制代码
npm install -g ts-node

检查安装是否成功:

ts-node -v

直接执行 .ts 文件:

ts-node test.ts

😲 这种方式是不是就稍微好玩了一些了呢❓

playground

最后,TS 官方也给我们提供了一个线上的 TS 环境,方便我们随时随地能进行 TS 代码的测试。

传送门 👈👈👈

tsconfig.json 文件

tsconfig.json 文件是 TS 的配置文件,一般放置于项目的根目录下。

它主要提供给 tsc 编译器使用,tsc 会在当前目录下搜索 tsconfig.json 文件,如果不存在,就会到上一级目录中搜索,直到找到为止,最后找不到会抛出错误。

你可以手动创建 tsconfig.json 文件,也可以通过 tsc 来自动创建。

javascript 复制代码
tsc --init

以下列举部分配置的说明,一般应该也足够用了的,更多配置的可以到官网上查阅。

json 复制代码
{
  "compilerOptions": {
      "incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
      "tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
      "diagnostics": true, // 打印诊断信息
      "target": "ES5", // 目标语言的版本
      "module": "CommonJS", // 生成代码的模板标准
      "outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
      "lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
      "allowJS": true, // 允许编译器编译JS,JSX文件
      "checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
      "outDir": "./dist", // 指定输出目录
      "rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
      "declaration": true, // 生成声明文件,开启后会自动生成声明文件
      "declarationDir": "./file", // 指定生成声明文件存放目录
      "emitDeclarationOnly": true, // 只生成声明文件,而不会生成js文件
      "sourceMap": true, // 生成目标文件的sourceMap文件
      "inlineSourceMap": true, // 生成目标文件的inline SourceMap,inline SourceMap会包含在生成的js文件中
      "declarationMap": true, // 为声明文件生成sourceMap
      "typeRoots": [], // 声明文件目录,默认时node_modules/@types
      "types": [], // 加载的声明文件包
      "removeComments":true, // 删除注释
      "noEmit": true, // 不输出文件,即编译后不会生成任何js文件
      "noEmitOnError": true, // 发送错误时不输出任何文件
      "noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
      "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
      "downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
      "strict": true, // 开启所有严格的类型检查
      "alwaysStrict": true, // 在代码中注入'use strict'
      "noImplicitAny": true, // 不允许隐式的any类型
      "strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
      "strictFunctionTypes": true, // 不允许函数参数双向协变
      "strictPropertyInitialization": true, // 类的实例属性必须初始化
      "strictBindCallApply": true, // 严格的bind/call/apply检查
      "noImplicitThis": true, // 不允许this有隐式的any类型
      "noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
      "noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
      "noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
      "noImplicitReturns": true, //每个分支都会有返回值
      "esModuleInterop": true, // 允许export=导出,由import from 导入
      "allowUmdGlobalAccess": true, // 允许在模块中全局变量的方式访问umd模块
      "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
      "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
      "paths": { // 路径映射,相对于baseUrl
        // 如使用jq时不想使用默认版本,而需要手动指定版本,可进行如下配置
        "jquery": ["node_modules/jquery/dist/jquery.min.js"]
      },
      "rootDirs": ["src","out"], // 将多个目录放在一个虚拟目录下,用于运行时,即编译后引入文件的位置可能发生变化,这也设置可以虚拟src和out在同一个目录下,不用再去改变路径也不会报错
      "listEmittedFiles": true, // 打印输出文件
      "listFiles": true// 打印编译的文件(包括引用的声明文件)
  }
  // 指定一个匹配列表(属于自动指定该路径下的所有ts相关文件)
  "include": [
     "src/**/*"
  ],
  // 指定一个排除列表(include的反向操作)
  "exclude": [
     "demo.ts"
  ],
  // 指定哪些文件使用该配置(需要手动一个个指定文件)
  "files": [
     "demo.ts"
  ]
}

基础类型注解

八种基础类型

到目前为止,JS 中一共有八种数据类型:number、string、boolean、null、undefined、object、symbol(ES6)、bigint(ES10)

javascript 复制代码
let a1: string = '橙某人';
let a2: number = 1;
let a3: boolean = true;
let a4: null = null;
let a5: undefined = undefined;
let a6: object = {};
let a7: bigint = 1n;
let a8: symbol = Symbol();

不知道你有没有注意到,上面定义类型的时候,类型名称首字母都是小写字母 ,这是因为首字母大写的 StringNumberBoolean 属于 JS 的内置对象。 (下面会解释两者的区别)

内置对象

JS 的内置对象有很多,如 NumberStringDateErrorRegExp 等等。

javascript 复制代码
let aa1: String = new String('橙某人');
let aa2: Number = new Number(1);
let aa3: Boolean = new Boolean(true); 
// let aa4: Null = null; ❌
// let aa5: Undefined = undefined; ❌
let aa6: Object = new Object({});
let aa7: BigInt = BigInt(1n);
let aa8: Symbol = Symbol();

let date: Date = new Date();
let error: Error = new Error('这是一个错误');
let reg: RegExp = new RegExp(/\a/);

大部分 ECMAScript 内置对象的类型定义: new 谁,类型就是谁。

注意🔉:

没有大写的 NullUndefined

undefinednull 既可以作为值,也可以作为类型,取决于在哪里使用它们。

undefinednull 是所有类型的子类型,在非严格模式下,可以赋值给任何类型。

🍊关于 number/string/booleanNumber/String/Boolean 的区别?

javascript 复制代码
let str: string = '橙某人';
let Str: String = new String('橙某人');

Str = str; // ✅
str = Str; // ❌

可以看到大写是包含小写的,你也可以认为小写是指更细致的类型,大写是指较宽松的类型。

其本质是因为 Numbernumber 的一个包装类型,关于什么是包装类型,可以看看这篇文章的介绍,传送门

下面贴上一张图,从上到下,类型越来越严格,下面的类型能分配给上面的类型,反之不行

DOM

DOM (Document Object Model) 即文档对象模型,指 Web 上构成文档结构和内容的对象的数据表示。说直白点就是指那些 HTML 标签在 JS 中的数据表示。

而在 TS 中有三种方式能定义 DOM 类型。

  • 其一,一般大部分的标签类型定义形式都是 HTML(标签名)Element
javascript 复制代码
let dom1: HTMLDivElement = document.createElement('div');
let dom2: HTMLInputElement = document.createElement('input');
let dom3: HTMLLabelElement = document.createElement('label');
  • 其二,如果是特殊的标签类型,可以定义成 HTMLElement 类型。
javascript 复制代码
let dom1: HTMLElement = document.createElement('header');
let dom2: HTMLElement = document.createElement('footer');
let dom3: HTMLElement = document.createElement('section');
  • 最后,Element 类型专治花里胡哨。
javascript 复制代码
let dom1: Element = document.createElement('div');
let dom2: Element = document.createElement('input');
let dom3: Element = document.createElement('label');

当然,如果你是一个比较严谨的人,那么你可以去 TS 源码中查看每个 DOM 的类型定义。传送门

以下小编拷贝了一些过来,可以作为一个参考👻:

javascript 复制代码
interface HTMLElementTagNameMap {
    "a": HTMLAnchorElement;
    "abbr": HTMLElement;
    "address": HTMLElement;
    "area": HTMLAreaElement;
    "article": HTMLElement;
    "aside": HTMLElement;
    "audio": HTMLAudioElement;
    "b": HTMLElement;
    "base": HTMLBaseElement;
    "bdi": HTMLElement;
    "bdo": HTMLElement;
    "blockquote": HTMLQuoteElement;
    "body": HTMLBodyElement;
    "br": HTMLBRElement;
    "button": HTMLButtonElement;
    "canvas": HTMLCanvasElement;
    "caption": HTMLTableCaptionElement;
    "cite": HTMLElement;
    "code": HTMLElement;
    "col": HTMLTableColElement;
    "colgroup": HTMLTableColElement;
    "data": HTMLDataElement;
    "datalist": HTMLDataListElement;
    "dd": HTMLElement;
    "del": HTMLModElement;
    "details": HTMLDetailsElement;
    "dfn": HTMLElement;
    "dialog": HTMLDialogElement;
    "dir": HTMLDirectoryElement;
    "div": HTMLDivElement;
    "dl": HTMLDListElement;
    "dt": HTMLElement;
    "em": HTMLElement;
    "embed": HTMLEmbedElement;
    "fieldset": HTMLFieldSetElement;
    "figcaption": HTMLElement;
    "figure": HTMLElement;
    "font": HTMLFontElement;
    "footer": HTMLElement;
    "form": HTMLFormElement;
    "frame": HTMLFrameElement;
    "frameset": HTMLFrameSetElement;
    "h1": HTMLHeadingElement;
    "h2": HTMLHeadingElement;
    "h3": HTMLHeadingElement;
    "h4": HTMLHeadingElement;
    "h5": HTMLHeadingElement;
    "h6": HTMLHeadingElement;
    "head": HTMLHeadElement;
    "header": HTMLElement;
    "hgroup": HTMLElement;
    "hr": HTMLHRElement;
    "html": HTMLHtmlElement;
    "i": HTMLElement;
    "iframe": HTMLIFrameElement;
    "img": HTMLImageElement;
    "input": HTMLInputElement;
    "ins": HTMLModElement;
    "kbd": HTMLElement;
    "label": HTMLLabelElement;
    "legend": HTMLLegendElement;
    "li": HTMLLIElement;
    "link": HTMLLinkElement;
    "main": HTMLElement;
    "map": HTMLMapElement;
    "mark": HTMLElement;
    "marquee": HTMLMarqueeElement;
    "menu": HTMLMenuElement;
    "meta": HTMLMetaElement;
    "meter": HTMLMeterElement;
    "nav": HTMLElement;
    "noscript": HTMLElement;
    "object": HTMLObjectElement;
    "ol": HTMLOListElement;
    "optgroup": HTMLOptGroupElement;
    "option": HTMLOptionElement;
    "output": HTMLOutputElement;
    "p": HTMLParagraphElement;
    "param": HTMLParamElement;
    "picture": HTMLPictureElement;
    "pre": HTMLPreElement;
    "progress": HTMLProgressElement;
    "q": HTMLQuoteElement;
    "rp": HTMLElement;
    "rt": HTMLElement;
    "ruby": HTMLElement;
    "s": HTMLElement;
    "samp": HTMLElement;
    "script": HTMLScriptElement;
    "section": HTMLElement;
    "select": HTMLSelectElement;
    "slot": HTMLSlotElement;
    "small": HTMLElement;
    "source": HTMLSourceElement;
    "span": HTMLSpanElement;
    "strong": HTMLElement;
    "style": HTMLStyleElement;
    "sub": HTMLElement;
    "summary": HTMLElement;
    "sup": HTMLElement;
    "table": HTMLTableElement;
    "tbody": HTMLTableSectionElement;
    "td": HTMLTableDataCellElement;
    "template": HTMLTemplateElement;
    "textarea": HTMLTextAreaElement;
    "tfoot": HTMLTableSectionElement;
    "th": HTMLTableHeaderCellElement;
    "thead": HTMLTableSectionElement;
    "time": HTMLTimeElement;
    "title": HTMLTitleElement;
    "tr": HTMLTableRowElement;
    "track": HTMLTrackElement;
    "u": HTMLElement;
    "ul": HTMLUListElement;
    "var": HTMLElement;
    "video": HTMLVideoElement;
    "wbr": HTMLElement;
}

🍊关于如何定义批量获取的 DOM 类型?

javascript 复制代码
let domArray1: NodeList = document.querySelectorAll('div');

// 以泛型的形式,后面会讲泛型
let domArray2: NodeListOf<HTMLDivElement | HTMLElement> = document.querySelectorAll('div') || document.querySelectorAll('p')

BOM

BOM (Browser Object Model) 即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window

TS 对于 BOM 对象的定义比较简单,只要首字母大写即可完成类型的定义。

javascript 复制代码
let win: Window = window;
let doc: Document = document;
let his: History = history;
let loc: Location = location;
let nav: Navigator = navigator;
let scr: Screen = screen;

不过也有一些是比较特殊的,这些都可以从 TS 的源码文件中查询得到。

javascript 复制代码
let coo: string = document.cookie
let locS: Storage = localStorage;

类型注解与类型推断

类型注解:指我们明确的注解一个变量的类型。

javascript 复制代码
let str: string = '橙某人';
let num: number = 1;
let bool: boolean = true;

类型推断 :指 TS 会根据上下文环境自动帮我们推断出变量的类型,无须我们再写明类型注解。

javascript 复制代码
let articleName = '橙某人';
let num = 1;
let bool = true;

以上两段代码是等价的。


本来这个 TS 通关秘籍是打算成写一篇文章,与小编另外两篇通关秘籍是一个系列,奈何小编吭哧吭哧在编辑器上写了两三周,复制过来却发不了。。。😭


至此,本篇文章就写完啦,撒花撒花。

希望本文对你有所帮助,如有任何疑问,期待你的留言哦。

老样子,点赞+评论=你会了,收藏=你精通了。

相关推荐
轻口味36 分钟前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami39 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡1 小时前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250032 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235952 小时前
web复习(三)
前端
AiFlutter2 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
麦兜*2 小时前
轮播图带详情插件、uniApp插件
前端·javascript·uni-app·vue