TS---基础

目录

TS的安装和运行:

TS相关介绍:

 (一) ts类型兼容性

对象类型兼容性

 函数类型兼容性

(二) ts.config.json文件介绍

(三) 类型声明文件介绍

(1) 类型声明文件作用

(2) 类型声明文件分类:内置-第三方提供-自定义

2.1 内置的文件

2.2 第三方库提供的文件:分为2种

2.3 自定义的类型文件

 (3) 类型声明文件的使用说明

常用的 TS 类型定义:

 一 原始数据类型

 二 数组类型

 三 联合类型 

 四 类型别名

 五 函数类型

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

2 . 同时指定参数、返回值的类型

3 . 可选参数

 六 对象类型

 1 . 对象中 方法类型 的两种语法

 2 . 对象类型 --- 可选属性 

 3 . 对象类型 --- 接口

 4 . interface 和 type 区别

 5 . 对象类型 --- 接口 interface 继承 extends

 6 . 使用交叉类型来实现 type 继承的功能

 七 元组类型

 八 类型推论

 九 字面量类型

 十 枚举类型 (了解)

 1 . 数字枚举

 2 . 字符串枚举

 3 . 枚举类型实现原理

 十一  any类型

 十二 类型断言 

 十三 typeof 运算符

 十四 泛型类型(高级类型-重点)

 1 . 泛型函数的创建和调用

 2 . 简化泛型函数调用

 3 . 泛型约束

 4 . 多个类型变量的泛型

 5 . 泛型接口(了解)

 6 . 泛型工具类型



TS的安装和运行

ts安装 (查看版本号):

npm i -g typescript  ( tsc -v)     

ts-node 安装(可直接运行ts文件):

 npm i -g ts-node (ts-node (文件路径)src/tsutil/01-hello.ts)

把当前ts环境变为模块化环境防止命名冲突 :

在当前文件中添加 export {} 即可,编译时可识别为模块化文件

ts-node运行ts报错时 :

先运行 tsc --init命令,初始化一下文件 


TS相关介绍:

 (一) ts类型兼容性

ts类型采用的是结构化类型系统(鸭子类型),根据结构识别是不是同一种类型,哪怕名字不一样

  • 对象类型兼容性

( 如果两个对象的类型结构一样,那么两个对象可以相互赋值,如果两个对象的类型结构不完全一样,那么成员多的对象可以赋值给成员少的对象 )

成员多的可以赋值给成员少的,至少满足基本的要求,多了没事,把一个值赋给某个类型的时候,只要满足这个类型的基本需求就行,例如Point2D需要2个属性,p3有3个属性,p3满足了Point2D基本的要求,就可以对p2进行赋值,把p3赋值给p2,它会检查等号左侧要求的内容等号右侧有没有,只要满足有的话就可以

  •  函数类型兼容性

( 考虑2个方面,参数个数 参数函数返回值

1. 函数参数个数类型:参数多的类型兼容参数少的(参数少的可以赋值给参数多的)

2. 函数返回值类型(和对象兼容性类似,只要满足的必须的类型要求就行,多了也可以)

 例如下面类型不要求有返回值,但是有返回值也可以。

(二) ts.config.json文件介绍

tsconfig文件介绍

(三) 类型声明文件介绍

(1) 类型声明文件作用

作用:用来为已存在的JS提供类型信息

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

 .ts文件:
1.既包含类型信息又可执行代码
2.可以被编译为js文件,然后,执行代码
3.用途:编写程序代码的地方


.d.ts文件:
1.只包含类型信息的类型声明文件
2.不会生成js文件,仅用于提供类型信息,在.dts文件中不允许出现可执行的代码,只用于提供类型
3.用途:为JS提供类型信息

总结:

  • .ts是implementation(代码实现文件------文件中可以有类型又可以有可执行的代码逻辑)
  • .d.ts是declaration(类型声明文件-----只包含类型信息的类型声明)
  • 如果要为JS库提供类型信息,要使用,d,ts文件

(2) 类型声明文件分类:内置-第三方提供-自定义

2.1 内置的文件

---比如数组foreach方法、window/document都有对应的类型声明

2.2 第三方库提供的文件:分为2种

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

  • 查看node_modules/axios目录。
  • 解释:这种情况下,正常导入该库,T$就会自动加载库自己的类型声明文件,以提供该库的类型声明。
  • VSCode中如何找到它的类型声明文件?就是在import导入包的时候,会读取axios的package.json中的types字段,来加载指定的类型声明文作

2.2.2 .由DefinitelyTyped提供

  •  DefinitelyTyped是一个github仓库,用来提供高质量TypeScript类型声明,DefinitelyTyped 链接
  • 可以通过npm/yam来下载该仓库提供的TS类型声明包,这些包的名称格式为:@types/*,比如,@types/react、.@types/lodash等。
  • 在实际项目开发时,如果你使用的第三方库没有自带的声明文件,VSCod会给出明确的提示
import _ from 'lodash'

//在VSCode中,鼠标移上去,查看'lodash'前面的提示

2.3 自定义的类型文件

在项目开发中,有两种常见情况,需要自己手动创建类型声明文件:

 2.3.1 项目内共享类型 , 如果多个.ts文件中都用到同一个类型,此时可以创建.d.ts文件提供该类型,实现类型共享

         操作步骤:

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

        (2)在index.d.ts中创建需要共享的类型,并使用export导出(TS中的类型也可以使用import/export实现模块化功能)

类型声明文件index.d.ts

export type NumStr = number | string

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

index.ts

import {NumStr} from './index.d.ts'
let b:NumStr = 1

   2.3.2 .为已有JS文件提供类型声明

        (1) 在将JS项目迁移到TS项目时,为了让已有的.js文件有类型声明,举例

        (2) 成为库作者,创建库给其他人使用

 (3) 类型声明文件的使用说明

  • 说明1:TS项目中也可以使用.js文件
  •  说明2:在导入.js文件时,TS会自动加载与js同名的.d.ts文件,以提供类型声明。

        (1) 比如,在导入index.js时,会自动加载index.d.ts类型声明文件

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

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

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


常用的 TS 类型定义

在实际的编程过程中,原始数据类型的类型定义是可以省略的,因为 TypeScript 会根据声明变量时赋值的类型,自动推导变量类型,也就是可以跟平时写 JavaScript 一样:

 一 原始数据类型

举几个例子

// 字符串类型

const str:string = 'Hello World'

// 数值类型

const num:number = 1

// 布尔值类型

const bool:boolean = true

// null 类型

const nullValue:null = null

//undefined类型
let undefinedValue:undefined = undefined
/E56中的Symbol类型
let uniqKey:symboI = Symbol()

 二 数组类型

这种写法 let nums:Array<string>["1","2","3"], 与下面等义,简单了解即可

创建数值类型的数组

const numbers:number[] = [1,2,3]

创建字符串类型的数组

const strings:string[] = ["1","2","3"]

 三 联合类型 

比如:数组中既有number类型,又有string类型

let arr:(number | string)[] = [1,'a',3,'b']

再举一个例子,下面这个函数接收一个代表 “计数” 的入参,并拼接成一句话打印到控制台,因为最终打印出来的句子是字符串,所以参数没有必要非得是数值,传字符串也是可以的,所以就可以使用联合类型:

// 可以在 demo 里运行这段代码
function counter(count: number | string) {
  console.log(`The current count is: ${count}.`)
}

// 不论传数值还是字符串,都可以达到的目的
counter(1)  // The current count is: 1.
counter('2')  // The current count is: 2.

 四 类型别名

  • 类型别名(自定义类型):为任意类型起别名
  • 使用场景:当同一类型(复杂)被多次使用时,可以通过类型别名,简化该类型的使用
  • 使用 type 关键字来创建自定义类型
  • 类型别名(比如,此处的CustomArray)可以是任意合法的变量名称
  • 推荐使用大写字母开头
type CustomArray =(number | string)[]
let arrl:CustomArray (1,'a'3,'b'l
let arr2:CustomArray ['x','y',6,7]

 五 函数类型

  • 函数的类型实际上指的是:函数参数返回值的类型
  • 如果函数没有返回值,那么,函数返回值类型为:void
  • 为函数指定类型的两种方式: 

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

函数的返回值类型直接在函数小括号后添加 类型注解 即可

//函数声明
function add(numl:number,num2:number):number{
    return numl+num2
}
//箭头函数
const add =(numl:number,num2:number):number =>{
    return numl+num2
}

2 . 同时指定参数、返回值的类型

  • 使用type关键字提前声明指定好函数参数、返回值的类型,这里使用箭头函数声明指定
  • 这种函数指定方式的使用只适用于箭头函数表达式
type AddFn = (num1:number,num2:number)=>number
const add3:AddFn = (num,num2)=> {
    return num1+num2
}

3 . 可选参数

  • 这里的num1就是可选参数,num2就是必选参数,如果不指定那么函数参数默认是必选的
  • 必选参数不能位于可选参数后
  • 当参数有 默认值 时,该参数默认就是可选参数,不需?指定为可选了,如num2:number=1
const add =(num1:number,num2?:number):number =>{
    return num1
}
add(3)

 六 对象类型

  • 对象类型的写法,对象类型实际上就是在描述对象的接口
  • 推荐使用type来指定对象的类型

 1 . 对象中 方法类型 的两种语法

  • type做类型声明 --- 函数声明式的写法 sing(name:string): void

type typeobj2 = {
    name: string
    sing(name:string): void
}

  • type做类型声明 --- 箭头函数式的写法 sing:(name:string)=>volid

type person = {
    sing:(name:string)=>volid
}

let obj2: { name: string; sing(): void } = {
    name: "ls",
    sing() { }
}

也可以同等于下面这种写法,用type先进行 类型别名 的声明再使用
type typeobj2 = {
    name: string
    sing(): void
}

let obj2: typeobj2  = {
    name: "ls",
    sing() { }
}

如果方法有参数,就在方法名后面的小括号中指定参数类型
type typeobj2 = {
    name: string
    sing(name:string): void
}
let obj2: typeobj2  = {
    name: "ls",
    sing(name) { }
}

// 箭头函数形式的方法类型
type person = {
    sing:(name:string)=>volid
}
let person:person  = {
    sing(name){}
}

 2 . 对象类型 --- 可选属性 

对象的属性默认也是必选的,在属性后面加上问号"?"就是可选属性,同函数类型的可选参数一致

比如我们封装api的函数,需要传递一些参数,有的参数需要传,有的不需要,
比如axios的get请求时,就可以省略methed属性,因为axios默认就是get请求
type Config = {
    url: string,
    method?: string,
}
const myAxios = (config:Config)=>{}

myAxios({
    url:"", // method这里是可选就可以不写
})

 3 . 对象类型 --- 接口

  • 可以使用  interface  关键字来为对象指定类型
  • 使用interface声明类型别名时,类型别名一般约定为大写I开头
  • interface 的使用方法和 type 基本一样

 4 . interface 和 type 区别

interface使用场景没有type多,一般尽量都使用type

相同点

  • 都可以给对象指定类型

 不同点

  • 接口 interface  只能为对象 指定类型
  • type  可以为任意类型指定 类型

 5 . 对象类型 --- 接口 interface 继承 extends

  • 接口继承的意思就是,如果两个接口之间有相同的属性和方法,可以将公共的属性或方法抽离出来,通过继承关键字 extends 来实现复用
  • 这里要注意使用type 这个自定义类型的关键字 声明的对象类型是没有办法继承的,只有interface才可以。

 

 6 . 使用交叉类型来实现 type 继承的功能

  • 使用 &符 进行类型的交叉使用
  • 后声明的类型写在&符后的{}里

 七 元组类型

  使用场景:

  • 在地图中,使用经纬度坐标来标记位置信息
  • 可以使用数值数组number[]来记录坐标但是不严谨,因为该类型的数组中可以出现多项数值.
  • 更好的方式,使用元组类型,元组 :Tuple

元组 :Tuple

  • 元组类型是另一种类型的数组
  • 它确切的标记出有多少个元素,以及特定索引对应的类型
  • react中的useState hook的返回值类型就是一个元组类型,因为对于useState来说,它的返回值长度固定且每个索引对应的元素类型也是知道的

使用元组来表示经纬度信息写法:

let pos:[number,number] = [116.6546, 863.5434]

 八 类型推论

在ts中,某些没有明确指出类型的地方,ts的类型推论机制会帮助提供类型

由于类型推论的存在,某些场景的类型注解可以省略不写(函数参数类型一定要写)

  • 第一种场景常见:声明变量并且初始化时,比如 let age = 10
  • 第二种场景常见:决定函数返回值时,比如:
    //这里函数的返回值类型就可以省略不写,自动推断为number类型
    const add =(numl:number,num2:number)=>{
        return numl+num2
    }
  • 第三中场景:绑定事件时:可以自动推断中事件对象的类型,比如:
    // e 参数自动分配了UIEvent类型,这个类型是window专属的
    // 事件中的事件对象可以自动推断
    window.addEventlistener('resize',(e)=>{})

    在编辑器中写代码时,多看方法属性的类型,养成写代码看类型的习惯

 九 字面量类型

字面量类型指的就是一个特定的值,一种值就是一种字面量类型,之前我们理解string,number是一种类型,字面量也是一种类型,字面量意思就是字面上能看出来这是个什么,你看到的一个值就是可以当做一个类型,比如对象数字等都可以当做一种类型,比如用const声明的变量,这个变量的类型就是变量的值,因为const本身就是声明常量的关键字它的值不能被改变。

  • 使用模式:字面量类型 配合 联合类型 一起使用
  • ,场景:用来表示一组明确的可选值列表,如我明确知道要选用的值,就可以声明一组和这个值相关的字面量类型。
    比如贪吃蛇游戏 方向可选值 只能是上下左右
    type Direction = 'up' | 'down' | 'left' | 'right'
    
    function changeDirection (direction: Direction){}
    
    changeDirection ('up')

 十 枚举类型 (了解)

  • 类似于字面量类型加联合类型组合的功能,也可以表示一组明确的可选值
  • 定义一组命名常量,它描述一个值,改值可以是这些命名常量中的一个
  • 枚举既可以作为一个类型,在调用的时候能看到枚举的类型也可以作为一个值出现

 1 . 数字枚举

  • 枚举成员是有值的,默认为是:从 0 开始的自增的数值
  • 我们把枚举成员的值为数字的枚举,称为 数字枚举
  • 也可以给枚举中的成员赋任意初始化值
    //指定了一个值后面值自增 down=11,left=12,right=13
    enum Direction {up = 10,down,left,right} 
    
    
    // 自定义值也可以
    enum Direction {up = 5,down = 8, left =17,right = 90} 
    

 2 . 字符串枚举

  • 枚举成员值是字符串
  • 字符串没有自增长行为,因为,字符串枚举的每个成员必须有初始值

 3 . 枚举类型实现原理

 十一  any类型

 

 十二 类型断言 

  • 使用场景:ts类型推断不准确的时候就可以使用类型断言
  • 语法:as 更加具体的类型
  • 如何获取标签的类型呢 

 十三 typeof 运算符

  • TS也提供了typeof操作符:可以在类型上下文中引用变量或属性的类型(类型查询)
  • 使用场景:根据已有变量的值,获取该值的类型,来简化类型书写
  • 1.使用 typeof 操作符来获取变量p的类型,结果与第一种(对象字面量形式的类型)相同
  • 2. typeof 出现在类型注解的位置(参数名称的冒号后面)所处的环境就是类型上下文(区别于JS代码)
  • 3. 注意:typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函敬调用的类型)

 十四 泛型类型(高级类型-重点)

 1 . 泛型函数的创建和调用

泛型可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class中

创建泛型函数:

function id<Type>(value:Type):Type return value
//也可以仅使用一个字母来作为类型变量的名称
function id<T>(value:T):T return value

调用泛型函数:  可传入任意类型,达到不同的类型一起工作。

const num = id<number>(10)
const str= id<string>('a')

解释:

  • 语法:在函数名称的后面添加<>(尖括号),尖括号中添加类型变量,比如此处的Type
  • 类型变量Type,是一种特殊类型的变量,它处理类型而不是值
  • 类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)
  • 因为Type是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型
  • 类型变量Type,可以是任意合法的变量名称

 2 . 简化泛型函数调用

const num = id(10)
const str= id('a')

解释:

  • 此时,TS内部会采用一种叫做类型参数推断的机制,来根据传入的实参自动推断出类型变量Type的类型
  • 比如,传入实参10,TS会自动推断出变量num的类型number,并作为Type的类型
  • 推荐:使用这种简化的方式调用泛型函数,使代码更短,更易于阅读
  • 说明:当编译器无法推断类型或者推断的类型不准确时,就需要显式地传入类型参数

 3 . 泛型约束

默认情况下,泛型函数的类型变量Tye可以代表任意类型,这导致无法访问任何属性,所以需要泛型约束

 此时,就需要为泛型添加约束来收缩类型(缩窄类型取值范围

 添加泛型约束收缩类型有两种方式:

(1)指定更加具体的类型

(2)添加泛型约束:使用extends关键字来添加类型约束

比如举个例子

  • 创建描述约束的接口ILength,该接口要求提供length属性
  • 通过extends关键字来为泛型(类型变量)添加约束
  • 该约束表示:传入的类型必须具有length属性

 4 . 多个类型变量的泛型

typeof ( 取到变量在ts中的类型 )

keyof ( 获取到对象Obj了中所有的属性,最终,会得到一个对象0bj中所有属性名称的联合类型 )

 5 . 泛型接口(了解)

 6 . 泛型工具类型

泛型工具文档

主要了解:

1.Partial<Type>
2.Readonly<Type>
3.Pick<Type,Keys>

Partial: Partial<Type>用来构造(创建)一个类型,将Type的所有属性设置为可选

type Props = {
  id:string
  children:number[]
}
type PartialProps = Partial<Props>
构造出来的新类型PartialProps结构和Props相同,但所有属性都变为可选的.

 Omit: Partial<Type>可以剔除 已定义对象中 自己不需要的一部分形成新的定义类型。

type Props = {
  id:string
  age:20
  name:'lisi'
}
type PartialProps = Omit<Props,'age'>
构造出来的新类型PartialProps结构不包含age属性,包含id和name属性

Readonly: Readonly<Type>用来构造(创建)一个类型,将Type的所有属性设置为只读

type Props = {
  id:string
  children:number[]
}
type ReadonlyProps = Readonly<Props>
构造出来的新类型ReadonlyProps 结构和Props相同,但所有属性都变为只读的.

错误演示
let props:ReadonlyProps ={id:'1',children:[]}
//会报错,错误演示,只读是无法修改的
props.id ='2'

Pick: Pick<Type,Keys> 从Type中选择一组属性来构造新类型,从一个对象类型中取出想要的几个属性,要几个取几个构成一个新的类型,举例:

interface Props {
  id:string,
  title:string,
  children:number[]
}
type PickProps = Pick<Props,'id'| 'title'>
// PickProps类型中 就只有两个属性了
  • Pck工具类型有两个类型变量:1表示选择谁的属性2表示选择哪几个属性。
  • 其中第二个类型变量,如果只选择一个则只传入该属性名即可。
  • 第二个类型变量传入的属性只能是第一个类型变量中存在的属性。
  • 构造出来的新类型PickProps,只有id和title两个属性类型。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
miniprogram-ts-less-quickstart是一个用于快速启动小程序开发的项目模板。它结合了TypeScript和Less两种前端技术,能够提供更好的开发体验和代码质量。 首先,TypeScript是JavaScript的超集,它增加了强类型、接口、泛型等特性,让编码更加健壮和可靠。使用TypeScript可以在开发过程中发现潜在的错误,提高开发效率。此外,TypeScript还支持ES6+的语法,并且提供了丰富的类型定义和IDE的支持,让我们能够更好地开展小程序开发工作。 另外,miniprogram-ts-less-quickstart还使用了Less作为CSS预处理器。Less可以增加CSS的可复用性和可维护性,提供了变量、嵌套规则、混入等特性,使得我们能够更加方便地编写和管理样式。通过使用Less,我们能够更好地组织样式代码,减少重复的工作,并且能够更容易地进行主题切换和样式调整。 miniprogram-ts-less-quickstart提供了一个基础的项目结构和一些常用的配置,使得我们能够快速上手开发。它包含了一些常用的开发工具和库,如webpack、eslint等,能够帮助我们提高开发效率和代码质量。此外,它还提供了一些示例代码和文档,让我们能够更好地理解和使用这个项目模板。 综上所述,miniprogram-ts-less-quickstart是一个非常有价值的项目模板,能够帮助我们快速启动小程序开发,并且提供了更好的开发体验和代码质量保障。它结合了TypeScript和Less两种前端技术,让我们能够更好地开展小程序开发工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值