一、为什么要用TypeScript

TypeScript能够让咱们开发中防止一些类型或者一些不是咱们预期心愿的代码后果谬误。xxx is not defined 咱们都晓得JavaScript谬误是在运行中才抛出的,然而TypeScript谬误间接是在编辑器里告知咱们的,这极大的晋升了开发效率,也不必花大量的工夫去写单测,同时也防止了大量的工夫排查Bug

二、TypeScript优缺点

长处

  • 个别咱们在前后端联调时,都要去看接口文档上的字段类型,而TypeScript会主动帮咱们辨认以后的类型。节俭了咱们去看文档或者network工夫。这叫做类型推导(待会咱们会讲到)
  • 敌对地在编辑器里提醒谬误,防止代码在运行时类型隐式转换踩坑。

毛病

  • 有肯定的学习老本,TypeScript中有几种类型概念,interface接口class类enum枚举generics泛型等这些须要咱们花工夫学习。
  • 可能和一些插件库联合的不是很完满

三、TypeScript运行流程及JavaScript代码运行流程

1. JavaScript运行流程如下,依赖NodeJs环境和浏览器环境

  • JavaScript代码转换为JavaScript-AST
  • AST代码转换为字节码
  • 运算时计算字节码

2. TypeScript运行流程,以下操作均为TSC操作,三步执行完持续同上操作,让浏览器解析

  • TypeScript代码编译为 TypeScript-AST
  • 查看AST代码上类型查看
  • 类型查看后,编译为JavaScript代码
  • JavaScript代码转换为JavaScript-AST
  • AST代码转换为字节码
  • 运算时计算字节码

四、TypeScript和JavaScript区别

只有搞懂了二者的区别,咱们才能够更好的了解TypeScript

类型零碎个性JavaScriptTypeScript
类型是如何绑定?动静动态
是否存在类型隐式转换?
何时查看类型?运行时编译时
何时报告谬误运行时编译时

类型绑定

JavaScript

JavaScript动静绑定类型,只有运行程序能力晓得类型,在程序运行之前JavaScript对类型无所不知

TypeScript

TypeScript是在程序运行前(也就是编译时)就会晓得以后是什么类型。当然如果该变量没有定义类型,那么TypeScript会主动类型推导进去。

类型转换

JavaScript

比方在JavaScript1 + true这样一个代码片段,JavaScript存在隐式转换,这时true会变成number类型number(true)和1相加。

TypeScript

TypeScript中,1+true这样的代码会在TypeScript中报错,提醒number类型不能和boolean类型进行运算。

何时查看类型

JavaScript

JavaScript中只有在程序运行时能力查看类型。类型也会存在隐式转换,很坑。

TypeScript

TypeScript中,在编译时就会查看类型,如果和预期的类型不合乎间接会在编辑器里报错、爆红

何时报告谬误

JavaScript

JavaScript只有在程序执行时能力抛出异样,JavaScript存在隐式转换,等咱们程序执行时能力真正的晓得代码类型是否是预期的类型,代码是不是无效。

TypeScript

TypeScript中,当你在编辑器写代码时,如有谬误则会间接抛出异样,极大得进步了效率,也是不便。

五、TypeScript总共围绕两种模式开展

显式注解类型

举个栗子

let name: string = "前端娱乐圈";let age: number = 38;let hobby: string[] = ["write code", "玩游戏"]

显式注解类型就是,申明变量时定义上类型(官网话语就是申明时带上注解),让咱们一看就明确,哦~,这个name是一个string类型。

推导类型

举个栗子

let name = "前端娱乐圈"; // 是一个string类型let age = 38;  // 是一个number类型let hobby = ["write code", "玩游戏"] // 是一个string数组类型

推导类型就是去掉显示注解,零碎主动会辨认以后值是一个什么类型的。

六、装置TypeScript && 运行

typescript

全局装置typescript环境。

npm i -g typescript

可是这只是装置了typescript,那咱们怎么运行.ts文件呢,装置完typescript咱们就能够执行tsc命令。

如:咱们的文件叫做index.ts,间接在命令行执行tsc index.ts即可。而后就能够看到在目录下编译进去一个index.js,这就是tsc编译完的后果。

index.ts

const userName: string = "前端娱乐圈" 

运行tsc index.ts,你能够看见在index.ts的同级下又生成一个index.js,如下就是编译的后果文件index.js

var userName = "前端娱乐圈"

下面咱们晓得了运行tsc命令就能够编译生成一个文件,有的小伙伴感觉这样太麻烦了,每次运行只是编译进去一个文件还不是运行,还得用node index.js才能够运行。不急咱们接着往下看

ts-node

咱们来看一下这个插件ts-node,这个插件能够间接运行.ts文件,并且也不会编译进去.js文件。

npm i ts-node// 运行 ts-node index.ts

讲到这里咱们理解了为什么要用TypeScript和它的优缺点以及它的运行工作形式

那么接下来步入TypeScript基础知识的陆地啦~,follow me。

感觉有帮忙的小伙伴能够关注一下:前端娱乐圈 公众号,谢谢啦~,每天更新一篇小技巧

七、基础知识

1. 根底动态类型

TypeScript中根底类型跟咱们JavScript中根底类型是一样的。只是有各别是Ts外面新出的。

1. number

const count: number = 18; // 显示注解一个number类型const count1 = 18; // 不显示注解,ts会主动推导进去类型

2. string

const str: string = "前端娱乐圈"; // 显示注解一个string类型const str1 = "蛙人"; // 不显示注解,ts会主动推导进去类型

3. boolean

const status: string = false; // 显示注解一个string类型const status1 = true; // 不显示注解,ts会主动推导进去类型

4. null

const value: null = null;const value: null = undefined; // 这一点null类型能够赋值undefined跟在 js中是一样的,null == undefined

5. undefined

const value: undefined = undefined;const value: undefined = null; // 这一点null类型能够赋值undefined跟在 js中是一样的,null == undefined

6. void

预计到这有一些小伙伴可能对void这个比拟生疏,认为只有TypeScript才有的。其实不是哈,在咱们JavaScript就曾经存在void关键字啦,它的意思就是有效的,有的小伙伴可能看见过早些我的项目外面<a href="javascript: void(0)">这是管制a标签的跳转默认行为。你不管怎么执行void办法它都是返回undefined

那么在咱们TypeScriptvoid类型是什么呢。它也是代表有效的,个别只用在函数上,通知他人这个函数没有返回值。

function fn(): void {} // 正确function testFn(): void {    return 1; // 报错,不承受返回值存在}function fn1(): void { return undefined} // 显示返回undefined类型,也是能够的function fn2(): void { return null} // 显示返回null类型也能够,因为 null == undefined

7. never

never一个永远不会有值的类型或者也能够说一个永远也执行不完的类型,代表用于不会有值,undefinednull也算做是值。个别这个类型就不会用到,也不必。大家晓得这个类型就行。

const test: never = null; // 谬误const test1: never = undefined // 谬误function Person(): never { // 正确,因为死循环了,始终执行不完    while(true) {}}function Person(): never { // 正确,因为递归,永远没有进口    Person()}function Person(): never { // 正确 代码报错了,执行不上来    throw new Error()}

8. any

any这个类型代表任何的任意的。心愿大家在我的项目中,不要大片定义any类型。尽管它真的好使,那这样咱们写TypeScript就没有任何意义了。

let value: any = ""; // 正确value = null // 正确value = {} // 正确value = undefined // 正确

9. unknown

unknown类型是咱们TypeScript中第二个any类型,也是承受任意的类型的值。它的英文翻译过去就是未知的,咱们来看一下栗子

let value: unknown = ""     value = 1;value = "fdsfs"value = nullvalue = {}

那当初必定有小伙伴纳闷,诶,那它unknown相当于是any类型,那二者的区别是什么。咱们来看一下

let valueAny: any = "";let valueUnknown: unknown = "";valueAny = "蛙人";valueUnknown = "前端娱乐圈"let status: null = false;status = valueAny; // 正确status = valueUnknown // 报错,不能将unknown类型调配给null类型

咱们来看一下下面的,为什么any类型就能被赋值胜利,而unknown类型不行呢,从它俩的意义来上看,还是有点区别的,any任何的,任意的、unknown未知的。所以你给unknown类型赋值任何类型都没关系,因为它原本就是未知类型嘛。然而你如果把它的unknown类型去被赋值一个null类型,这时人家null这边不干了,我不承受unknown类型。

说白了一句话,他人不承受unknown类型,而unknown类型承受他人,哈哈哈哈。

2. 对象动态类型

说起对象类型,咱们必定都能想到对象蕴含{}数组函数

1. object && {}

其实这俩意思一样,{}object示意非原始类型,也就是除numberstringbooleansymbolnullundefined之外的类型。

const list: object = {} // 空对象const list1: object = null; // null对象const list: object = [] // 数组对象const list: {} = {}list.name = 1 // 报错 不可更改外面的字段,然而能够读取list.toString()

2. 数组

const list: [] = []; // 定义一个数组类型const list1: number[] = [1,2] // 定义一个数组,外面值必须是numberconst list2: object[] = [null, {}, []] // 定义一个数组外面必须是对象类型的const list3: Array<number> = [1,2,3] // 泛型定义数组必须是number类型,泛型咱们待会讲到

3. 类

// 类class ClassPerson = {    name: "前端娱乐圈"}const person: ClassPerson = new Person();person.xxx = 123; // 这行代码报错,因为以后类中不存在该xxx属性

4. 函数

// 函数const fn: () => string = () => "前端娱乐圈" // 定义一个变量必须是函数类型的,返回值必须是string类型

3. 函数类型注解

这里说一下函数显示注解和函数参数不会类型推导问题。

1. 函数返回类型为number

function fn(a, b): number {    return a + b;}fn(1, 2)

2. 函数void

显示注解为void类型,函数没有返回值。

function fn(): void {    console.log(1)}

3. 函数不会主动类型推导

能够看到上面的函数类型,不会主动类型推导,咱们实参尽管传入的1和2,然而形参方面是能够承受任意类型值的,所以零碎也辨认不进去你传递的什么,所以这里得须要咱们显示定义注解类型。

function testFnQ(a, b) {    return a + b}testFnQ(1,2)

咱们来革新一下。

function testFnQ(a:number, b:number) {    return a + b}testFnQ(1,2)

咱们再来看一下参数对象显示注解类型,也是在:号前面赋值每个字段类型即可。

function testFnQ(obj : {num: number}) {    return obj.num}testFnQ({num: 18})

4. 元组Tuple

元组用于示意一个已知数组的数量和类型的数组,定义数组中每一个值的类型,个别不常常应用。

const arr: [string, number] = ["前端娱乐圈", 1]const arr: [string, string] = ["前端娱乐圈", 1] // 报错

5. 枚举Enum

Enum枚举类型,能够设置默认值,如果不设置则为索引。

enum color {    RED,    BLUE = "blue",    GREEN = "green"}// color["RED"] 0// color["BLUE"] blue

像下面的colorRED没有设置值,那么它的值则为0,如果BLUE也不设置的话那么它的值则是1,它们这里是递增。如果设置值则是返回设置的值

留神这里还有一个问题,间接来上代码

通过下面学习咱们晓得了enum能够递增值,也能够设置默认值。然而有一点得留神一下,enum没有json对象那样灵便,enum不能在任意字段上设置默认值。

比方上面栗子,RED没有设置值,而后BLUE设置了默认值,然而GREEN又没有设置,这时这个GREEN会报错。因为你第二个BLUE设置完默认值,第三又不设置,这时代码都不晓得该咋递增了,所以报错。还有一种计划就是你给BLUE能够设置一个数字值,这时第三个GREEN不设置也会跟着递增,因为都是number类型。

// 报错enum color {    RED,    BLUE = "blue",    GREEN}// goodenum color {    RED,       // 0    BLUE = 4,  // 4    GREEN      // 5}

比方enum枚举类型还能够反差,通过valuekey值。像咱们json对象就是不反对这种写法的。

enum color {    RED,       // 0    BLUE = 4,  // 4    GREEN      // 5}console.log(color[4]) // BLUEconsole.log(color[0]) // RED

5. 接口Interface

接口interface是什么,接口interface就是不便咱们定义一处代码,多处复用。接口外面也存在一些修饰符。上面咱们来认识一下它们吧。

1. 接口怎么复用

比方在讲到这之前,咱们不晓得接口这货色,可能须要给对象定义一个类型的话,你可能会这样做。

const testObj: { name: string, age: number } = { name: "前端娱乐圈", age: 18 }const testObj1: { name: string, age: number } = { name: "蛙人", age: 18 }

咱们用接口来革新一下。

interface Types {    name: string,     age: number}const testObj: Types = { name: "前端娱乐圈", age: 18 }const testObj1: Types = { name: "蛙人", age: 18 }

能够看到应用interface关键字定义一个接口,而后赋值给这两个变量,实现复用。

2. readonly修饰符

readonly类型,只可读状态,不可更改。

interface Types {    readonly name: string,     readonly age: number}const testObj: Types = { name: "前端娱乐圈", age: 18 }const testObj1: Types = { name: "蛙人", age: 18 }testObj.name = "张三" // 无奈更改name属性,因为它是只读属性testObj1.name = "李四" // 无奈更改name属性,因为它是只读属性

3. ?可选修饰符

可选修饰符以?定义,为什么须要可选修饰符呢,因为如果咱们不写可选修饰符,那interface外面的属性都是必填的。

interface Types {    readonly name: string,     readonly age: number,    sex?: string}const testObj: Types = { name: "前端娱乐圈", age: 18}

4. extends继承

咱们的interface也是能够继承的,跟ES6Class类一样,应用extends关键字。

interface Types {    readonly name: string,     readonly age: number,    sex?: string}interface ChildrenType extends Types { // 这ChildrenType接口就曾经继承了父级Types接口    hobby: []}    const testObj: ChildrenType = { name: "前端娱乐圈", age: 18, hobby: ["code", "羽毛球"] }

5. propName扩大

interface外面这个性能就很弱小,它能够写入不在interface外面的属性。

interface Types {    readonly name: string,     readonly age: number,    sex?: string,}const testObj: Types = { name: "前端娱乐圈", age: 19, hobby: [] } 

下面这个testObj这行代码会爆红,因为hobby属性不存在interface接口中,那么咱们不存在的接口中的,还不让人家写了?。这时候能够应用自定义就是下面的propName

interface Types {    readonly name: string,     readonly age: number,    sex?: string,    [propName: string]: any // propName字段必须是 string类型 or number类型。 值是any类型,也就是任意的}const testObj: Types = { name: "前端娱乐圈", age: 19, hobby: [] } 

在运行下面代码,就能够看到不爆红了~

6. Type

咱们再来看一下Type,这个是申明类型别名使的,别名类型只能定义是:根底动态类型对象动态类型元组联结类型

留神:type别名不能够定义interface
type Types = string;type TypeUnite = string | numberconst name: typeUnite = "前端娱乐圈"const age: typeUnite = 18

1. 那么type类型别名和interface接口有什么区别呢

1. type不反对interface申明
type Types = numbertype Types = string // 报错, 类型别名type不容许呈现反复名字interface Types1 {    name: string}interface Types1 {    age: number}// interface接口能够呈现反复类型名称,如果反复呈现则是,合并起来也就是变成 { name:string, age: number }

第一个Types类型别名type不容许呈现反复名字,interface接口能够呈现反复类型名称,如果反复呈现则是,合并起来也就是变 { name:string, age: number }

再来看一下interface另一种状况

interface Types1 {    name: string}interface Types1 {    name: number}

能够看到下面两个同名称的interface接口,外面的属性也是同名称,然而类型不一样。这第二个的Types1就会爆红,提醒:后续申明的接口,必须跟后面申明的同名属性类型必须保持一致,把后续申明的name它类型换成string即可。

2. type反对表达式 interface不反对
const count: number = 123type testType = typeof countconst count: number = 123interface testType {    [name: typeof count]: any // 报错}

能够看到下面type反对表达式,而interface不反对

3. type 反对类型映射,interface不反对
type keys = "name" | "age"  type KeysObj = {    [propName in keys]: string}const PersonObj: KeysObj = { // 失常运行    name: "蛙人",    age: "18"} interface testType {    [propName in keys]: string // 报错}

7. 联结类型

联结类型|示意,说白了就是满足其中的一个类型就能够。

const statusTest: string | number = "前端娱乐圈"const flag: boolean | number = true

再来看一下栗子。咱们用函数参数应用联结类型看看会产生什么

function testStatusFn(params: number | string) {    console.log(params.toFixed()) // 报错}testStatusFn(1)

下面咱们说过了,函数参数类型不能类型主动推导,更何况当初用上联结类型,零碎更懵逼了,不能辨认以后实参的类型。所以拜访以后类型上的办法报错。

接下来带大家看一些类型爱护,听着挺高级,其实这些大家都见过。别忘了记得关注:前端娱乐圈 公众号哦,嘻嘻

1. typeof

function testStatusFn(params: number | string) {    console.log(params.toFixed()) // 报错}testStatusFn(1)

革新后

// 失常function testStatusFn(params: string | number) {    if (typeof params == "string") {        console.log(params.split)    }    if (typeof params == "number") {        console.log(params.toFixed)    }}testStatusFn(1)

2. in

// 报错interface frontEnd {    name: string}interface backEnd {    age: string}function testStatusFn(params: frontEnd | backEnd) {    console.log(params.name)}testStatusFn({name: "蛙人"})

革新后

// 失常function testStatusFn(params: frontEnd | backEnd) {    if ("name" in params) {        console.log(params.name)    }    if ("age" in params) {        console.log(params.age)    }}testStatusFn({name: "蛙人"})

3. as 断言

// 报错interface frontEnd {    name: string}interface backEnd {    age: string}function testStatusFn(params: frontEnd | backEnd) {    console.log(params.name)}testStatusFn({name: "蛙人"})

革新后

// 失常function testStatusFn(params: frontEnd | backEnd) {    if ("name" in params) {        const res = (params as frontEnd).name        console.log(res)    }            if ("age" in params) {        const res = (params as backEnd).age        console.log(res)    }}testStatusFn({age: 118})

8. 穿插类型

穿插类型就是跟联结类型相同,它用&示意,穿插类型就是两个类型必须存在。这里还用下面的联结类型的栗子来看下。

interface frontEnd {    name: string}interface backEnd {    age: number}function testStatusFn(params: frontEnd & backEnd) {}testStatusFn({age: 118, name: "前端娱乐圈"})

这里咱们能够看到实参必须传入两个接口(interface)全副的属性值才能够。联结类型是传入其中类型就能够。

留神:咱们的接口interface呈现同名属性

interface frontEnd {    name: string}interface backEnd {    name: number}function testStatusFn(params: frontEnd & backEnd) {    console.log(params)}testStatusFn({name: "前端"})

下面咱们两个接口类型中都呈现了同名属性,然而类型不一样,这时类型就会变为never

<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/51e337707b6641e590bbb0139fabacdb~tplv-k3u1fbpfcp-watermark.image" width="90%">

9. 泛型

泛型是TypeScript中最难了解的了,这里我尽量用通俗易懂的形式讲明确。

function test(a: string | number, b: string | number) {    console.log(a, b)}test(1, "前端娱乐圈")

比方下面栗子,函数参数注解类型定义stringnumber,调用函数实参传入也没什么问题,然而有个需要,就是实参咱们必须传入同样的类型(传入两个number类型)。尽管下面这种联结类型也能够实现,然而如果咱们要在加一个boolean类型,那么联结类型还得在追加一个boolean,那这样代码太冗余了。

这时就须要用到泛型了,泛型是专门针对不确定的类型应用,并且灵便。泛型的应用大部分都是应用<T>,当然也能够轻易应用,如:<Test><Custom>都能够。

function test<T>(a: T, b: T) {    console.log(a, b)}test<number>(1, "前端娱乐圈") // 调用前面跟着尖括号这就是泛型的类型,这时报错,因为在调用的应用类型是number,所以只能传入雷同类型的test<boolean>(true, false) test<string>("前端娱乐圈", "蛙人")

下面这应用泛型就解决了咱们方才说的传入同一个类型参数问题,然而泛型也能够应用不同的参数,能够把调用类型定义为<any>

function test<T>(a: T, b: T) {    console.log(a, b)}test<any>(1, "前端娱乐圈")

然而下面这种又有一种问题,它能够传入对象,然而如果咱们只心愿传入number类型和string类型。那么咱们泛型也给咱们提供了束缚类型。泛型应用extends进行了类型束缚,只能抉择stringnumber类型。

function test<T extends number | string, Y extends number | string>(a: T, b: Y) {    console.log(a, b)}test<number, string>(18, "前端娱乐圈")test<string, number>("前端娱乐圈", 18)

这时,传入泛型时应用逗号分隔,来定义每一个类型心愿是什么。记住,只有咱们不确定的类型,能够应用泛型。

10. 模块

TypeScript也反对importexport这里大多数小伙伴都晓得,这里都不多讲啦。

// 导入import xxx, { xxx } from "./xxx"// 导出export default {}export const name = "前端娱乐圈"

如有不明确的小伙伴,能够看我以前文章 聊聊什么是CommonJs和Es Module及它们的区别

11. Class类

以下这三个修饰符是在TypeScript类中能力应用,在JavaScript类中是不反对的。

1. public

public的公共属性,就是不论在的外部还是内部,都能够拜访该属性办法。默认定义的属性办法都是public

class Person {    name = "前端娱乐圈";    public age = 18;}const res = new Person();console.log(res.name, res.age) // 前端娱乐圈 18

下面能够看到打印后果都能显示进去,name属性没有定义public公共属性,所以外面定义的属性办法默认都是public定义。

2. private

private的公有属性,只有在以后外面能力拜访,以后就是{}外面区域内。在{}里面是不能拜访private定义的属性办法

class Person {    private name = "前端娱乐圈";    private age = 18;}const res = new Person();console.log(res.name, res.age) // 这俩行会爆红,以后属性为公有属性,只能在类外部拜访class Scholl extends Person {    getData() {        return this.username + "," + this.age    }}const temp = new Scholl()console.log(temp.getData()) // 爆红~,尽管继承了Person类,然而private定义是只能在以后类拜访,子类也不能拜访。

3. protected

protected的爱护属性,只有在以后类子类能够拜访。也就是说用protected属性定义的子类也能够拜访。

class Person {    protected username = "前端娱乐圈";    protected age = 18;}const res = new Person();console.log(res.name, res.age) // 这俩行会爆红,以后属性为公有属性,只能在类外部拜访class Scholl extends Person {    getData() {        return this.username + "," + this.age    }}const temp = new Scholl()console.log(temp.getData()) // 前端娱乐圈,18。能够失常拜访父类的属性

4. implements

implements关键字只能在class中应用,顾名思义,实现一个新的类,从父级或者从接口实现所有的属性和办法,如果在PersonAll类外面不写进去接口外面已有的属性和办法则会报错。

interface frontEnd {    name: string,    fn: () => void}class PersonAll implements frontEnd {    name: "前端娱乐圈";        fn() {            }}

5. 抽象类

抽象类应用abstract关键字定义。abstract形象办法不能实例化,如果,抽象类外面办法是形象的,那么自身的类也必须是形象的,形象办法不能写函数体。父类外面有形象办法,那么子类也必须要从新该办法。

// 抽象类abstract class Boss {    name = "秦";    call() {} // 形象办法不能写函数体}class A extends Boss {    call() {        console.log(this.name);        console.log("A")    }}class B extends Boss {    call() {         console.log("B")    }}new A().call()

该抽象类应用场景,比方A需要或者B需要正好须要一个公共属性,而后自身还有一些本人的逻辑,就能够应用抽象类,抽象类只能在TypeScript中应用。

12. 命名空间namespace

咱们学到当初能够看到,不晓得小伙伴们发现没有,我的项目中文件是不是不能有反复的变量(不论你是不是一样的文件还是其它文件),否则就间接爆红了。命名空间一个最明确的目标就是解决重名问题。

命名空间应用namespace关键字来定义,来看栗子吧。

index.ts

namespace SomeNameSpaceName {     const q = {}    export interface obj {        name: string    }}

下面这样,就定义好了一个命名空间,能够看到变量q没有写export关键字,这证实它是外部的变量,就算别的.ts文件援用它,它也不会裸露进来。而interface这个obj接口是能够被全局拜访的。

咱们在别的页面拜访以后命名空间

1. reference引入

/// <reference path="./index.ts" />namespace SomeNameSpaceName {     export class person implements obj {        name: "前端娱乐圈"    }}

2. import

export interface valueData {     name: string}
import { valueData } from "./xxx.ts"

这时应用命名空间之后齐全能够解决不同文件重名爆红问题。

13. tsConfig.json

这个tsconfig文件,是咱们编译ts文件,如何将ts文件编译成咱们的js文件。tsc -init这个命令会生成该文件进去哈。执行完该命令,咱们能够看到根目录下会生成一个tsconfig.json文件,外面有一堆属性。

那么咱们怎么将ts文件编译成js文件呢,间接执行tsc命令能够将根目录下所有的.ts文件全副编译成.js文件输入到我的项目下。

更多配置文档,请参考官网

{    // include: ["*.ts"] // 执行目录下所有的ts文件转换成js文件    // include: ["index.ts"] // 只将我的项目下index.ts文件转换为js文件    // files: ["index.ts"] // 跟include一样,只执行以后数组值外面的文件,以后files必须写相对路径    // exclude: ["index.ts"] // exclude就是除了index.ts不执行,其它都执行        compilerOptions: {        removeComments: true, // 去掉编译完js文件的正文        outDir: "./build", // 最终输入的js文件目录        rootDir: "./src", // ts入口文件查找    }}

八、实用类型

最初来说一下实用类型,TypeScript规范库自带了一些实用类型。这些实用类都是不便接口Interface应用。这里只列举几个罕用的,更多实用类型官网

1. Exclude

从一个类型中排除另一个类型,只能是联结类型,从TypesTest类型中排除UtilityLast类型。

实用于:并集类型

interface UtilityFirst {    name: string}interface UtilityLast {    age: number}type TypesTest = UtilityFirst | UtilityLast;const ObjJson: Exclude<TypesTest, UtilityLast> = {    name: "前端娱乐圈"}

2. Extract

Extract正好跟下面那个相同,这是抉择某一个可赋值的联结类型,从TypesTest类型中只抉择UtilityLast类型。

实用于:并集类型

interface UtilityFirst {    name: string}interface UtilityLast {    age: number}type TypesTest = UtilityFirst | UtilityLast;const ObjJson: Extract<TypesTest, UtilityLast> = {    age: 1}

3. Readonly

把数组或对象的所有属性值转换为只读的。这里只演示一下对象栗子,数组同样的写法。

实用于:对象、数组

interface UtilityFirst {    name: string}const ObjJson: Readonly<UtilityFirst> = {    name: "前端娱乐圈"}ObjJson.name = "蛙人" // 报错 只读状态

4. Partial

把对象的所有属性设置为可选的。咱们晓得interface只有不设置?修饰符,那么对象都是必选的。这个实用类能够将属性全副转换为可选的。

实用于:对象

interface UtilityFirst {    name: string}const ObjJson: Partial<UtilityFirst> = {    }

5. Pick

Pick选择对象类型中的局部key值,提取进去。第一个参数目标值,第二个参数联结key

实用于:对象

interface UtilityFirst {    name: string,    age: number,    hobby: []}const ObjJson: Pick<UtilityFirst, "name" | "age"> = {    name: "前端娱乐圈",    age: 18}

6. Omit

Omit选择对象类型中的局部key值,过滤掉。第一个参数目标值,第二个参数联结key

实用于:对象

interface UtilityFirst {    name: string,    age: number,    hobby: string[]}const ObjJson: Omit<UtilityFirst, "name" | "age"> = {    hobby: ["code", "羽毛球"]}

7. Required

Required把对象所有可选属性转换成必选属性。

实用于:对象

interface UtilityFirst {    name?: string,    age?: number,    hobby?: string[]}const ObjJson: Required<UtilityFirst> = {    name: "蛙人",    age: 18,    hobby: ["code"]}

8. Record

创立一个对象后果集,第一个参数则是key值,第二个参数则是value值。规定咱们只能创立这外面字段值。

实用于:对象

type IndexList = 0 | 1 | 2const ObjJson: Record<IndexList, "前端娱乐圈"> = {    0: "前端娱乐圈",    1: "前端娱乐圈",    2: "前端娱乐圈"}

九、闲聊

给在北京通州租房小伙伴们提个醒,最近被这狗B小房地产公司坑了,租房到期成心不退押金,大家在通州找房的小伙伴们留神一下,千万别碰见这家狗中介公司,这家公司注册一堆公司名,北京珺奇地产北京珺邺地产等,打着二十一世纪旗号成心骗人。你们必定问我为啥找这么小公司租房,特马的这里还得吐槽一下这个某居客App,我第一次用这个App租房,没想到这外面都是一堆相似于这种的小中介公司,真的很恶心。租房还得找大公司,靠谱安心。

感激

谢谢你读完本篇文章,心愿对你能有所帮忙,如有问题欢送各位斧正。
我是蛙人,如果感觉写得能够的话,请点个赞吧❤。
感兴趣的小伙伴能够退出 [ 前端娱乐圈交换群 ] 欢送大家一起来交换探讨
写作不易,「点赞」+「在看」+「转发」 谢谢反对❤
下篇更新TypeScript实战,欢送关注

参考资料

  • https://www.cnblogs.com/mengf...
  • 了不起的 TypeScript 入门教程
  • TypeScript编程实体书
  • TypeScript中文网