TypeScript:熟练掌握TypeScript

目录

一、TypeScript简介

二、TypeScript为什么要为js增加类型支持?

三、TypeScript 对比 JS 的优势

四、安装TypeScript

五、在命令行里边执行ts文件

六、语法学习

6.1、理解类型声明

6.2、常用类型概述

6.3、类型注解

6.4、常用类型分类

6.5、原始类型

6.6、数组类型

6.7、联合类型

6.8、类型别名

6.9、函数类型(1,单独指定参数和返回值的类型)

6.10、函数类型(同时指定参数和返回值的类型)

6.11、void类型

6.12、函数可选参数

6.13、对象类型

6.14、对象可选属性

6.15、接口

6.16、接口和类型别名的对比

6.17、接口继承

6.18、元组

6.19、类型推论

6.20、类型断言

6.21、字面量类型

6.22、枚举类型

6.23、枚举成员的值以及数字枚举

6.24、字符串枚举

6.25、枚举的特点及原理

6.26、any类型

6.27、TS中的typeof运算符

6.28、TS高级类型概述

6.29、class的基本使用

6.30、class的构造函数

6.31、class的实例方法

6.32、class继承(extends)

6.33、class继承(implements)

6.34、class类的可见性修饰符(3-1 public)

6.35、class类的可见性修饰符(3-2 protected)

6.36、class类的可见性修饰符(3-3 private)

6.37、readonly只读修饰符

6.38、类型兼容性的说明

6.39、对象之间的类型兼容性

6.40、接口之间的类型兼容性

6.41、函数之间的类型兼容性(3-1,函数参数)

6.42、函数之间的类型兼容性(3-2,函数参数)

6.43、函数之间的类型兼容性(3-3,返回值)

6.44、交叉类型

6.45、交叉类型和接口之间的对比说明

6.46、泛型的基本使用

6.47、简化泛型函数调用

6.48、泛型约束

6.49、泛型约束(extends添加约束)

6.50、多个泛型变量的情况

6.51、泛型接口

6.52、数组式泛型接口

6.53、泛型类

6.55、泛型工具类型(readonly)

6.56、泛型工具类型(pick)

6.57、泛型工具类型(record)

6.58、索引签名类型

6.59、映射类型

6.60、映射类型(keyof)

6.61、分析泛型工具类型partial的实现

6.62、索引查询类型(基本使用)

6.63、索引查询类型(同时查多个)

6.64、类型声明文件概述

6.65、TS中的两种文件类型

6.66、使用已有的类型声明文件(1,内置类型声明文件)

6.67、使用已有的类型声明文件(2,第三方库的类型声明文件)

6.68、创建自己的类型声明文件(3-1,项目内共享类型)

6.69、创建自己的类型声明文件(3-2,为已有js文件提供类型的声明概述)

6.70、创建自己的类型声明文件(3-3,为已有js文件提供类型的声明)

6.71、TS配置文件tsconfig.json的说明

6.72、通过命令方式使用编译配置

七、过程记录


一、TypeScript简介

TypeScript 是一种由 Microsoft 开发的静态类型编程语言,它是 JavaScript 的超集,意味着它包含了 JavaScript 中所有的特性并且添加了更多的功能。

TypeScript 的主要特点是静态类型检查,可以在编译时发现类型错误,而不是在运行时;还有类、接口、命名空间、泛型等多种功能,可以提高代码的可读性、可维护性和重用性。

TypeScript 可以运行在任何支持 JavaScript 的平台上,包括浏览器、Node.js、移动应用和服务器应用等。它可以使用 JavaScript 的任何库和框架,并且支持类型声明文件,可以为第三方库提供类型定义,以便在开发时提供更好的代码补全和语法检查。

相对于 JavaScript,TypeScript 需要额外的编译过程,将 TypeScript 代码编译成 JavaScript 代码,但这个过程可以使用 TypeScript 提供的编译工具自动完成,无需手动操作。

总的来说,TypeScript 是一种可靠、可扩展、易于维护的编程语言,适合用于大型项目的开发和维护,并且可以与 JavaScript 无缝集成。

简单理解就是:

TypeScript (简称:TS)是JavaScript的超集 (JS有的TS 都有)。

TypeScript=Type +JavaScript (在JS 基础之上,为JS添加了类型支持)。

TypeScript 教程 | 菜鸟教程

哔哩哔哩_教程_TypeScript

二、TypeScript为什么要为js增加类型支持?

背景:JS的类型系统存在“先天缺陷”,J5代码中绝大部分错误都是类型错误(UncaughtTypeError)。
问题:增加了找 Bug、改 Bug 的时间,严重影响开发效率。
从编程语言的动静来区分,TypeScript属于静态类型的编程语言,JS属于动态类型的编程语言。
静态类型:编译期做类型检查;
动态类型:执行期做类型检查代码;
编译和代码执行的顺序:1编译 2执行。
对于JS来说:需要等到代码真正去执行的时候才能发现错误 (晚)。
对于TS来说:在代码编译的时候 (代码执行前)就可以发现错误 (早)。
并且,配合VSCode 等开发工具,T5 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改Bug 时间。

三、TypeScript 对比 JS 的优势

3.1、更早 (写代码的同时)发现错误,减少找 Bug、改 Bug 时间,提升开发效率。

3.2、程序中任何位置的代码都有代码提示,随时随地的安全感,增强了开发体验和信心。

3.3、强大的类型系统提升了代码的可维护性,使得重构代码更加容易。

3.4、支持最新的 ECMAScript 语法,优先体验最新的语法,让你走在前端技术的最前沿。

3.5、 类型推断机制,不需要在代码中的每个地方都显示标注类型,让你在享受优势的同时,尽量降低了成本。

3.6、Vue3源码使用TS重写、Angular默认支持TS、React与TS完美配合,TypeScript已成为大中型前端项目的首选编程语言。

四、安装TypeScript

4.1、通过npm(Node.js包管理器)

npm install -g typescript

yarn add -g typescript

 pnpm add -g typescript

4.2、查看版本

tsc -v 

4.3、ts-node ,不需要每次修改都执行ts文件,可以简化操作。

pnpm add ts-node

4.4、使用 

ts-node hello.ts

  

五、在命令行里边执行ts文件

tsc test.ts

六、语法学习

6.1、理解类型声明

<template>
    <div>
        <h1>TypeSctipt</h1>

        <div>{{ age }}</div>
    </div>
</template>

<script setup lang="ts">

// 有明确的类型,即: number
let age: number = 20

</script>

<style scoped>
</style>

6.2、常用类型概述

TypeScript是JS的超集,TS提供了JS的所有功能,并且额外的增加了:类型系统。

所有的JS代码都是TS代码。

JS有类型(比如,number/string等),但是JS不会检查变量的类型是否发生变量。而TS会检查。

TypeScript类型系统的主要优势:可以显示标记处代码中的意外行为,从而降低了发生错误的可能性。

6.3、类型注解

let name: string = 'snow'

说明:代码中的 string 就是类型注解。

作用:为变量添加类型约束。比如,上述代码中,约定变量name的类型为string(字符串类型)。

解释:约定了什么类型,就只能给变量赋值该类型的值, 否则就会报错。

6.4、常用类型分类

JS已有类型

原始类型:number、string、boolean、null、undefined、symbol

对象类型:object(包括:数组、对象、函数)

TS新增类型

联合类型、自定义类型(类型别名)、接口、元组、字面量类型、枚举、void、any等。

6.5、原始类型

原始类型:number、string、boolean、null、undefined、symbol

特点:简单。这些类型,完全按照js中类型的名称来书写。

let age: number = 18
let name: string = 'snow'
let isLoading: boolean = false
let a: null = null
let b: undefined = undefined
let c: symbol = Symbol()
// 等等...

6.6、数组类型

let numbers: number[] = [1, 2, 3] // 推荐用法,使用直观
let strings: Array<string> = ['a', 'b', 'c']

// 数组中既有number类型,又有string类型
let arr: (number | string)[] = [1, 2, 3, 'a', 'b', 'c']
// 解释:| (竖线)在TS中叫做联合类型(由两个或多个其他类型组成的类型,表示可以是这些类型中的任意一种)。
// 注意:这是TS中的联合类型的语法,只有一根竖线,不要与js中的或(|)混淆了。

let b: boolean[] = [true, false, true, false]

6.7、联合类型

需求:数组中既有 number 类型,又有 string 类型,这个数组的类型应该如何写?

let arr: (number | string)[] = [1, 2, 3, 'a', 'b', 'c'] // 正确

let arr1: number | string[] = 123 // 正确
let arr2: number | string[] = ['a', 'b', 'c'] // 正确
let arr3: number | string[] = [1, 2, 3] // 错误

解释:| (竖线)在TS中叫做联合类型,由两个或多个其他类型组成的类型,表示可以是这些类型中的任意一种。

注意:这是TS中联合类型的语法,只有一根竖线,不要与JS中的(||)混淆了。 

6.8、类型别名

类型别名(自定义类型):为任意类型起别名。

使用场景:当同一类型(复杂)被多次使用时,可以通过类型别名,简化该类型的使用。

type snow = (number | string)[]
let arr1: snow = [1, 2, 3, 'a', 'b', 'c']

解释:

1,使用 type 关键字来创建类型别名。

2,类型别名(比如,此处的snow),可以是任意合法的变量名称。

3,创建类型别名后,直接使用该类型别名作为变量的类型注解即可。

6.9、函数类型(1,单独指定参数和返回值的类型)

函数的类型实际上指的是:函数的参数和返回值的类型。

为函数指定类型的两种方式:1单独指定参数、返回值的类型 2 同时指定参数、返回值的类型。

1、单独指定参数、返回值的类型:

// 普通函数
function add(num1: number, num2: number): number{
    return num1 + num2
}
// 箭头函数
const add = (num1: number, num2: number): number => {
    return num1 + num2
}

定义了参数,调用时候需要传入对应类型的参数。 返回值同理(除了void、any)。

6.10、函数类型(同时指定参数和返回值的类型)

const add: (num1: number, num2: number) => number = (num1, num2) => {
    return num1 + num2
}

因为前边参数加过类型了,后边就不需要再指定了。

解释:当函数作为表达式时,可以通过类似箭头函数的语法来为函数添加类型。

注意:这种形式只适用于函数表达式。 

6.11、void类型

如果函数没有返回值,那么,函数返回值的类型为:void。

function snow(name: string) :vlid {
    console.log(name)
}

void:语义为空。

使用场景:没有返回值时候 使用 返回值类型 void。

6.12、函数可选参数

使用函数实现某个功能时,参数可以传也可以不传。这种情况下,在给函数参数指定类型时,就用到了可选参数。比如slice()方法,可以slice()也可以slice(1)还可以slice(1, 2)。

function snowSlice(start?: number, end?: number): void {
    console.log('起始索引:' start, '结束索引:', end)
} 

function snowSlice2(start: number, end?: number): void {
    console.log('起始索引:' start, '结束索引:', end)
} 

可选参数:在可传可不传的参数名称后面添加?(问号)。

注意:可选参数只能出现在参数列表的最后,也就是说可选参数后面不能再出现必选参数。 

6.13、对象类型

let person: { name: string; age: number; sayHi(): void} = {
    name: 'snow',
    age: 18,
    sayHi(){}
}

解释:

1、直接使用{}来描述对象结构。属性采用属性名:类型的形式;方法采用方法名():返回值类型的形式。

2、如果方法有参数,就在方法名后面的小括号中指定参数类型(比如:greet(name:string

):void)。

3、在一行代码中指定对象的多个属性类型时,使用;(分号)来隔开。

如果一行代码只指定一个属性类型(通过换行来分隔多个属性类型),可以去掉;(分号)。

方法的类型也可以使用箭头函数的形式(比如:{sayHi:()=> void})。 

6.14、对象可选属性

对象的属性或方法,也可以是可选的,此时就用到了可选属性。

比如,我们在使用axios({...})时,如果发送GET请求,method属性就是可以省略的。

function myAxios(config: {url: string; method?: string}){
    console.log(config)
}

可选属性的语法于函数可选参数的语法一致,都使用?(问好)来表示。

6.15、接口

当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到服用的目的。

interface IPerson {
    name: string
    age: number
    sayHi(): void
}

let person: IPerson = {
    name: 'snow',
    age: 18,
    sayHi(){}
}

解释:

1、使用interface关键字来声明接口。

2、接口名称(比如,此处的IPerson),可以是任意合法的变量名。

3、声明接口后,直接使用接口名称作为变量的类型。

4、因为每一行只有一个属性类型,因此,属性类型后没有;(分号)。

6.16、接口和类型别名的对比

21-接口和类型别名的对比_哔哩哔哩_bilibili

相同点:都可以给对象指定类型。

不同点:

接口,只能为对象指定类型。

类型别名:不仅可以为对象指定类型,实际上可以为任意类型指定别名。

interface IPerson{

        name: string

        age: number

        sayHi(): void

}

type IPersion = {

        name: string

        age: number

        sayHi(): void

type NumStr = number | string 

6.17、接口继承

如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承实现服用。比如,这两个x、y两个属性,重复写两次,可以,但很繁琐。

interface Point2D { x: number; y: number;}

interface Point3D { x: number; y: number; z: number }

更好的方式:

interface Point2D { x: number; y: number }

interface Point3D extends Point2D { z: number } 

 解释:

1、使用extends(继承)关键字实现了接口Point3D继承Point2D。

2、继承后,Point3D 就有了Point2D的所有属性和方法(此时,Point3D同时有 x,y,z三个属性)。

6.18、元组

场景:在地图中,使用经纬度坐标记录位置信息。
可以使用数组来记录坐标,那么,该数组中只有两个元素,并且这两个元素都是数值类型。

let position: number[] = [39.5427, 116.2317]

使用number[] 的缺点:不严谨,因为该类型中数组可以出现任意多个数字。

更好的方式可以使用“元组”。

元组类型是另一种类型的数组,它确切的知道包含多少个元素,及特定索引对应的类型。

let position: [number, number] = [39.5427, 116.2317] 

解释:

1、元组类型可以确切的标记出有多少个元素,及每个元素的类型。

2、该实例中,元素有两个元素,每个元素的类型都是number。 

6.19、类型推论

在TS中,某些没有明确指出类型的地方,TS的类型推断机制回帮助提供类型。

换句话说:由于类型推论的存在,这些地方,类型注解可以省略不写!

发生类型推论的两种场景:1、声明变量并初始化时;2、决定函数返回值时。

let age = 18 // TS自动推断出变量 age 为 number 类型

function add(num1: number, num2: number) { return num1 + num2 } 

注意:这两种情况下,类型注解可以省略不写!

推荐:能省略注解的地方就省略(偷懒,充分利用TS类型推论的能力,提升开发效率)

技巧:如果不知道类型,可以通过鼠标放在标量名称上,利用VSCode的提示来查看类型。 

6.20、类型断言

有时候你会比TS更加明确一个值的类型,此时,可以使用类型断言来指定更具体的类型。

举例一

<a href="https:www.snow.com" id="link">snow</a>

const aLink = document.getElementById("link") 

注意:getElementById方法返回值的类型是HTMLElement,该类型只包含所有标签的属性或方法,不包含a标签特有的href等属性。

因此,这个类型太宽泛(不具体),无法操作href等a标签特有的属性或方法。

解决方式:这种情况下就需要使用类型断言指定更加具体的类型。 

const aLink = document.getElementById("link") as HTMLAnchorElement

解释:
1、使用as关键字实现类型断言。
2、关键字 as 后面的类型是一个更加具体的类型(HTMLAnchorElement是HTMLElement的子类型)
3、通过类型断言 ,aLink的类型变得更加具体,这样就可以访问a标签特有的属性或方法了。

另一种语法,使用<>语法,这种语法形式不常用知道即可:

const aLink = <HTMLAnchorElement>document.getElementById("link")

技巧:在浏览器控制台,通过console.dir() 打印DOM元素,在属性列表的最后面,即可看到该元素的类型。

vue3+ts:shims-vue.d.ts_snow@li的博客-CSDN博客

6.21、字面量类型

思考一下代码,两个变量的类型分别是什么?

let str1 = "Hello TS"
const str2 =  "Hello TS"

通过TS类型推论机制,可以得到答案:
1、变量str1 的类型为:string
2、变量str2 的类型为:"Hello TS"

解释:
1、str1是一个变量(let),它的值可以是任意字符串,所以类型为:string
2、str2是一个常量(const),它的值不能变化只能是"Hello TS",所以它的类型为:"Hello TS"。

注意:此处的"Hello TS",就是一个字面量类型。也就是说某个特定的字符串也可以作为TS中的类型。除字符串外,任意的js字面量(比如,对象、数字等)都可以作为类型使用。

使用模式:字面量类型配合联合类型一起使用。

使用场景:用来标识一组明确的可选值列表。

比如,在贪吃蛇游戏中,游戏的方向可选值只能是 “上、下、左、右” 中的任意一个 

function changeDirection(direction: "up" | "down" | "left" | "right"){
        console.log(direction)
}

解释:参数direction的值只能是up/down/left/right中的任意一个。

优势:相比于string类型,使用字面量类型更加精确、严谨。 

6.22、枚举类型

枚举的功能类似于字面量类型+联合类型组合的功能,也可以标识一组明确的可选值。

枚举:定义一组命名常量。它描述一个值,该值可以是这些命名常量中的一个。

enum Direction { Up, Down, Left, Right }

function changeDirection(direction: Direction) {
    console.log(direction)
}

解释:
1、使用 enum 关键字定义枚举。
2、约定枚举名称,枚举中的值以大写字母开头。
3、枚举中多个值之间通过 ,(逗号)分隔。
4、定义枚举后,直接使用枚举名称作为类型注解。 

6.23、枚举成员的值以及数字枚举

问题:我们把枚举成员作为了函数的实参,它的值是什么呢?

changeDirection(Direction.Up)

解释:通过将鼠标移入Direction.Up,可以看到枚举成员Up的值为0。

注意:枚举成员是有值的,默认为:从0开始自增的数值。

我们把,枚举成员的值为数字的枚举,称为:数字枚举。

当然,也可以给枚举中的成员初始化值。

enum Direction { Up = 10, Down, Left, Right } 

 enum Direction { Up = 10, Down = 4, Left = 8, Right = 16 } 

6.24、字符串枚举

字符串枚举:枚举成员的值是字符串。

enum Direction {
        Up = "UP",

        Down = "DOWN",

        Left = "LEFT",

        Right = "RIGHT"
}

注意:字符串枚举没有自增长行为(不能一部分是数字类型,一部分是字符串类型),因此,字符串枚举的每个成员必须有初始值。

6.25、枚举的特点及原理

枚举是TS为数不多的非JavaScript类型及扩展(不仅仅是类型)的特性之一。
因为:其他类型仅仅被当做类型,而枚举不仅用作类型,还提供值(枚举成员都是有值的)。
也就是说,其他的类型会在编译为js代码时自动移除。但是,枚举型会编译为js代码。

说明,枚举与前面讲到的字面量类型+联合类型组合的功能类似,都用来表示一组明确的可选值列表。
一般情况下,推荐使用字面量类型+联合类型组合的方式,因为相比枚举,这种方式更加直观、简洁、高效。

6.26、any类型

原则:不推荐any!这会让TypeScript变为AnyScript,这样失去TypeScript类型的优势。
因为当值类型为any时,可以对该值进行任意操作,并且不会有代码提示。

let obj: any = { x: 0}
obj.bar = 100
obj()
const n: number = obj

解释:以上操作都不会有任何类型提示,即使可能存在错误!
尽可能 的避免使用any类型,除非临时使用any来”避免“书写很长、很复杂的类型!
其他隐式具有any类型的情况:1声明变量不提供类型也不提供默认值;2函数参数不加类型。
注意:因为不推荐使用any,所以,这两种情况下都应该提供类型!

6.27、TS中的typeof运算符

我们知道,js中提供了typeof操作符,用来在js中获取数据的类型。

console.log(typeof "hello world")

实际上,TS也提供了typeof操作符,可以在类型上下文中引用变量或属性的类型(类型查询)。
使用场景:根据已有变量的值,获取该值的类型,来简化类型的书写。 

let p = { x:1, y:2 }
function formatPoint(point: {x: number; y: number}){}
formatPoint(p)
function formatPoint(point: typeof p)

解释:
1、使用 typeof 操作符来获取变量p的类型,结果与第一种(对象字面量形式的类型)相同。
2、typeof 出现在类型注解的位置(参数名称的冒号后面)做处的环境就在类型上下文(区别于js代码)
3、注意:typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型,比如,函数调用的类型。 

6.28、TS高级类型概述

TS中高级类型有很多,重点学习以下高级类型:

class类型

类型兼容性

交叉类型

泛型 和 keyof

索引签名类型 和 索引查询类型

映射类型

6.29、class的基本使用

TypeScript全面支持ES2015中引入class关键字,并为其添加了类型注解和其他语法(比如,可以见修饰符) 
class基本使用:

class Person{}
        const p: Person
const p = new Person()

解释:
1、根据TS中的类型推论,可以知道Person类的实例对象p的类型是Person
2、TS中的class 不仅提供了class的语法功能,也作为一种类型的存在。 

6.30、class的构造函数

class Persion {
    age: number
    gender: string
    
    constructor(age: number, gender: string) {
        this.age = age
        this.gender = gender
    }
}

解释:

1、成员初始化(比如,age: number)后,才可以通过this.age来访问实例成员。

2、需要为构造函数指定类型注解,否则会被隐式推断为any;构造函数不需要返回值类型。 

6.31、class的实例方法

class Point {
    x = 10
    y = 10


    scale(n: nunber): void{
        this.x += n
        this.y += n
    }
}

解释:方法的类型注解(参数和返回值)与函数用法相同。

6.32、class继承(extends)

继承类的两种方式:
1、extends(继承父类);2、implements(实现接口)
说明:js中只有extends,而implements是TS提供的。

class Animal {
    move() { console.log('moving') }
}

class Dog extends Animal {
    bark() { console.log('汪汪汪!') }
}

const dog = new Dog()

解释:

1、通过extends关键字实现继承。

2、子类Dog继承父类Animal,则Dog的实例对象dog就同时具有了父类Animal和子类Dog的所有方法。

6.33、class继承(implements)

继承类的两种方式:
1、extends(继承父类);2、implements(实现接口)

interface Singable {
    sing(): void
}

class Person implements Singable {
    sing () {
        console.log('我是snow')
    }
}

解释:

1、通过implements关键字让class实现接口。

2、Person类实现接口Singable意味着,Person类中必须提供Singable接口中指定的所有方法和属性。

6.34、class类的可见性修饰符(3-1 public)

类成员可见性:可以使用TS来控制class的方法或属性对于class外的代码是否可见。
可见性修饰符包括:1,public(公有的);2,protected(受保护的);3,private(私有的)
public:表示共有的、公开的,公有成员可以被任务地方访问,默认可见性。

class Animal {
        public move() {

                console.log('moving')

        }
}

解释:

1、在类属性或方法前面添加public关键字,来修饰该属性或方法是共有的。

2、因为public是默认可见性,所以,可以直接省略。

 14-class类的可见性修饰符(1public)_哔哩哔哩_bilibili

6.35、class类的可见性修饰符(3-2 protected)

protected:表示受保护,仅对其声明所在类和子类中(非实例对象)可见。

class Animal {

        protected move (){

                console.log('moving')

        }

}

class Dog extends Animal {

        bark() {

                console.log('汪汪汪!')

                this.move()

        }

}

解释:

1、在类属性或方法前面添加protected关键字,来修饰该属性或方法是受保护的。

2、在子类的方法内部可以通过this来访问父类中受保护的成员,但是,对实例不可见!

6.36、class类的可见性修饰符(3-3 private)

private:表示私有的,只在当前类中可见,对实例对象以及子类也是不可见的。

class Animal {

        private move () {

                console.log('moving')

        }

        walk() {

                this.move()

        }

}

解释:

1、在类属性或方法前面添加private关键字,来修饰该属性或方法是私有的。

2、私有的属性或方法只在当前类中可见,对子类和实例对象也都是不可见的!

6.37、readonly只读修饰符

除了可见性修饰符之外,还有一个常见修饰符就是:readonly(只读性修饰符)。

readonly:表示只读,用来防止在构造函数之外对属性进行赋值。

class Person {

        readonly age: number = 18

        constructor(age: number) {

                this.age = age

        }

}

解释:

1、使用readonly关键字修饰该属性只读的,注意只能修改属性,不能修饰方法。

2、注意:属性age后面的类型注解(比如,此处的number)如果不加,则age的类型为18(字面量类型)

3、接口或者{}表示的对象类型,也可以使用readonly。

6.38、类型兼容性的说明

类中类型系统:1、StructuralType System(结构化类型系统)2、Nominal Type System(表明类型系统)。

TS采用的是结构化类型系统,也叫做duck typing(鸭子类型),类型检查关注的是值所具有的形式。

也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为他们属于同一类型。

class Point {x: number; y: number}

class Point2D {x: number; y: number}

const p: Point = new Point2D()

解释:

1、Point 和 Point2D是两个名称不同的类。

2、变量p的类型被显示标注为Point类型,但是,它的值却是Point2D的实例,并且没有类型错误。

3、因为TS是结构化类型系统,只检查Point和Point2D的结构是否相同(相同,都具有x和y两个属性,属性类型也相同)

4、但是,如果在Nominal Type System中(比如,c#、Java等),他们是不同的类,类型无法兼容。 

6.39、对象之间的类型兼容性

注意:在结构化类型系统中,如果两个对象具有相同的形状,则认为他们属于同一类型,这种说法并不准确。更准确的说法:对于对象类型来说,y的成员至少与x相同,则x兼容y(成员多的可以赋值给少的)。

class Point {x: number; y: number}

class Point3D {x: number; y: number;z: number}

const p: Point = new Point3D()

解释:

1、Point3D的成员至少与Point相同,则Point兼容Point3D。

2、所以,成员多的Point3D可以赋值给成员少的Point。 

6.40、接口之间的类型兼容性

6.41、函数之间的类型兼容性(3-1,函数参数)

6.42、函数之间的类型兼容性(3-2,函数参数)

6.43、函数之间的类型兼容性(3-3,返回值)

6.44、交叉类型

6.45、交叉类型和接口之间的对比说明

6.46、泛型的基本使用<T>

TypeScript中泛型<T>详细讲解 - 南风晚来晚相识 - 博客园

6.47、简化泛型函数调用

6.48、泛型约束

6.49、泛型约束(extends添加约束)

6.50、多个泛型变量的情况

6.51、泛型接口

6.52、数组式泛型接口

6.53、泛型类

6.54、泛型工具类型(partial)

6.55、泛型工具类型(readonly)

6.56、泛型工具类型(pick)

6.57、泛型工具类型(record)

6.58、索引签名类型

6.59、映射类型

6.60、映射类型(keyof)

6.61、分析泛型工具类型partial的实现

6.62、索引查询类型(基本使用)

6.63、索引查询类型(同时查多个)

6.64、类型声明文件概述

6.65、TS中的两种文件类型

TS中有两种文件类型:1 .ts文件 2 .d.ts文件

.ts文件:

1、既包含类型信息又可执行代码。

2、可以被编译为.js文件,然后,执行代码。

3、用途:编写程序代码的地方。

.d.ts文件:

1、只包含类型信息的类型声明文件。

2、不会生成.js文件,仅用于提供类型信息。

3、用途:为js提供类型信息。

总结:.ts是implementation(代码实现文件);.d.ts是declaration(类型声明文件)。

如果要为js库提供类型信息,要使用.d.ts文件。

这两个文件在TS项目里边很重要,比如在vue3+TS或者uniapp+vue3+TS项目中遇到类型报错,首先考虑是不是这两个文件的配置问题。

6.66、使用已有的类型声明文件(1,内置类型声明文件)

在使用TS开发项目时,类型声明文件的使用包括一下两种方式:

1、使用已有的类型声明文件

2、创建自己的类型声明文件

学习顺序:先会用(别人的)再会写(自己的)

6.67、使用已有的类型声明文件(2,第三方库的类型声明文件)

第三方库的类型声明文件:目前,几乎所有的常用的第三方库都有响应的类型声明文件。

第三方库的类型声明文件有两种存在形式:1库自带类型声明文件;2由DefinitelyTyped提供。

库自带类型声明文件,比如,axios

解释:

这种情况下,正常导入该库,TS就会自动加载库自己的类型声明文件,以提供该库的类型声明。 

6.68、创建自己的类型声明文件(3-1,项目内共享类型)

​​​​​​​​​​​​​​类型声明文件的使用说明

创渖自己的类型声明文件: 1 顶目内共亨型 2 为已到 JS 文侔璺供类声

顶目内共享类型:如累多个文中都用到一个类生,此时可以创建 .d.ts 文件提供该类型·实现类型共享

操作步骤

创建 index.d.ts 类型声明文件

创建需共享的类型,并使用export导出( TS 中的类型也可以使用import / export 实现模诀化功能)

在需要使用共享类型的文件中,通过import导入即可(.d.ts后缀导入时,直接省酪)

6.69、创建自己的类型声明文件(3-2,为已有js文件提供类型的声明概述)

​​​​​​​类型声明文件的使用说明

创建自己的类型声明文件:1,项目内共享类型;2,为已有JS文件提供类型声明。

为已有js文件提供类型声明:1,在将js项目迁移到ts项目时,为了已有的.js文件有类型声明。2、或为库作者,创建给其他人使用。

注意:类型声明文件的模块化方式相关,不同的模块化方式有不同的写法。但由于历史原因,js模块化的发展经历过多种变化(AMD. CommonJS 、 UMD. ES Module 等),而ts支持各种模块化形式的类型声明。这就导致,类型声明文件又多又杂。

演示:基于最新的ESModule(import / export)来为已有.js文件,创建类型声明文件。

开发环境准备:使用webpack搭建,通过ts-loader处理.ts文件

6.70、创建自己的类型声明文件(3-3,为已有js文件提供类型的声明)

类型文件的使用说明

为已有js文件提供类型声明:

说明:TS项目中也可以使用.js文件。

说明:在导入.js文件时,TS会自动加载与.js同名的.d.ts文件,以提供类型声明。

declare 关键字,用于类型声明,为其他地方(比如,.js文件)已存在的变量声明类型,而不是创建一个新的变量。

1、对于type、interface等这些明确就是TS类型的(只能在TS中使用的),可以节省declare关键字

2、对于let、function等具有双重含义(在JS、TS中都能用),应该使用declare关键字,明确指定此处用于类型声明。

6.71、TS配置文件tsconfig.json的说明

tsconfig.json是TypeScript编译器的配置文件,它定义了编译器的设置和编译选项。该文件用于指定编译项目的根目录、输出目录、编译选项等设置。

常见的配置选项
序号配置项说明
1compilerOptions它定义了编译器的设置和编译选项,包括target、module、lib、declaration、outDir、sourceMap等。
2include它用于指定需要编译的文件或文件夹的路径。
3exclude它用于指定不需要编译的文件或文件夹的路径。
4files它用于指定需要编译的文件列表。
5extends它允许继承其他tsconfig.json文件的设置。

使用tsconfig.json可以简化编译步骤,提高编译效率,并且使得编译的设置更加统一和可维护。

注意:TS的配置项非常多(100+),使用时一定要认真查看文档。

1、tsconfig.json文件所在目录为项目根目录(与package.json同级)。

2、tsconfig.json可以自动生成,命令:tsc --init。

6.72、通过命令方式使用编译配置

除了在tsconfig.json文件中使用编译配置外,还可以通过命令行来使用。

使用演示:tsc hello.ts --target es6

注意:

1、tsc后带有输入文件时候(比如,tschello.ts),将忽略tsconfig.json文件。

2、tsc后不带输入文件时(比如,tsc),才会启用tsconfig.json

推荐使用:tsconfig.json配置文件

七、过程记录

7.1、ts的(.d.ts)文件

TypeScript的`.d.ts`文件(Declaration File)是用来描述JavaScript库、模块或者其他代码的类型信息的文件。`.d.ts`文件中包含了类型声明、接口、类等的定义,这些定义可以让其他TypeScript代码理解和使用这些JavaScript代码。`.d.ts`文件可以手动编写,也可以使用工具自动生成。
`.d.ts`文件是在类型系统中非常重要的一种文件类型,因为它们允许TypeScript开发者在编写代码时获得类型检查和自动补全的支持,从而提高开发效率和代码质量。

一文读懂TS的(.d.ts)文件 - 简书

八、本文第六章学习内容来自 哔哩哔哩_黑马程序员_TypeScript 感谢UP分享,本文仅用于记录学习过程,如有侵权立即删除。

九、欢迎交流指正,关注我,一起学习。

十、参考链接

vue3+ts:shims-vue.d.ts_snow@li的博客-CSDN博客

TypeScript超详细入门教程(上)_星河_赵梓宇的博客-CSDN博客

学习TypeScript4这一篇就够了_轻松的小希的博客-CSDN博客

03-TS相比JS的优势_哔哩哔哩_bilibili

1小时快速入门typescript_哔哩哔哩_bilibili

21-接口和类型别名的对比_哔哩哔哩_bilibili

GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

TypeScript 教程 | 菜鸟教程

TS错误信息列表_JinmyHe的博客-CSDN博客_跳转目标不能跨越函数边界

20_泛型_哔哩哔哩_bilibili

5分钟上手TypeScript · TypeScript中文网 · TypeScript——JavaScript的超集

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值