【学】通俗易懂的 TypeScript(二)

93 阅读5分钟

内置类型

声明文件

声明文件

@types 官方声明文件库@types 搜索声明库

内置类型

内置类型

大家可以看到这个类型,不同的文件中有多处定义,但是它们都是 内部定义的一部分,然后根据不同的版本或者功能合并在了一起,一个interface 或者 类多次定义会合并在一起。这些文件一般都是以 lib 开头,以 d.ts 结尾,告诉大家,我是一个内置对象类型。

Utility Types

Typescript 还提供了一些功能性,帮助性的类型,这些类型,大家在 js 的世界是看不到的,这些类型叫做 utility types,提供一些简洁明快而且非常方便的功能。

// partial,它可以把传入的类型都变成可选
interface IPerson {
  name: string
  age: number
}

let p1: IPerson = {name: 'viking', age: 20}

type IPartial = Partial<IPerson>

let p2: IPartial = {}

// Omit,它返回的类型可以忽略传入类型的某个属性
type IOmit = Omit<IPerson, 'name'>
let p3: IOmit = {age: 20}

类型演算

根据已知的信息,计算出新的类型

typeof

  1. TS中的typeof,书写的位置在类型约束的位置上。表示:获取某个数据的类型
  • 获取数据的类型

无论是变量还是函数,都可以通过typeof获取目标本身的类型

interface Person {
  name: string
  age: number
}

const t1: Person = {
  name: '111',
  age: 11
}

// 获取数据t1 的类型
type P1 = typeof t1 // P1 类型为 Person
const t2: P1 = {
  name: '111',
  age: 11
}

//函数
function toArr(x:number):number[]{
  return [x]
}
type a1 = typeof toArr //type a1 = (x:number) => number[]
  • 获取type类型
type Point = {x: number; y: number}
type P = keyof Point //p的值可以为 'x' | 'y'
const a: P = 'x'

// Error: 不能将类型“1”分配给类型“"x" | "y"”。ts(2322)
const b: P = 1
  1. 当typeof作用于的时候,得到的类型是该类的构造函数
class User {
  loginid: string
  logingpwd: string
}

function createUser(cls: typeof User): User {
  return new cls()
}

const u = createUser(User)

keyof

作用于类、接口、类型别名,用于获取其他类型中的所有成员名组成的联合类型

import {userInfo} from 'os'

interface User {
  name: string
  age: number
  userid: number
}

const kU: keyof User = 'name' // 'name' | 'age' | 'userid'

image.png

in

该关键字往往和keyof联用,限制某个索引类型的取值范围

interface User {
  loginId: string
  loginpwd: string
  age: number
}

// type Obj = {
//   loginId: string
//   loginpwd: string
//   age: string
// }

// type Obj = {
//   [p in 'loginId' | 'loginpwd' | 'age']: string
// }

type Obj = {
  // 将User的所有属性值类型变成字符串,得到一个新类型
  [p in keyof User]: string
}

const u: Obj = {
  loginId: '1',
  loginpwd: '2',
  age: '3'
}

TS中预设的类型演算

Partial<T>    //将类型T中的成员变为可选
Required<T>    //将类型T中的成员变为必填
Readonly<T> //将类型T中的成员变为只读
Exc1ude<T,U>  //从T中剔除可以赋值给U的类型
Extract<T,U>  //提取T中可以赋值给U的类型。
NonNullable<T>  //从T中易别除nul1和undefined。
ReturnType<T> //获取函数返回值类型。
InstanceType<T> //获取构造函数类型的实例类型。

声明文件

概述

  1. 什么是声明文件?

.d.ts 结尾的文件。

  1. 声明文件有什么用?

为JS代码提供类型声明

  1. 声明文件的位置?

放置到tsconfig.json 配置 include 包含的目录中。

{
  "compilerOptions": {},
  // src 及其子目录都有效。
  "include": ["./src"]
}

放置到node_modules/@types 文件夹中。

手动配置。

与JS代码所在目录相同, 并且文件名也相同的文件

编写

  1. 自动生成

工程是使用ts开发的,发布(编译)之后,是js文件,发布的是js文件。

如果发布的文件,需要其他开发者使用,可以使用声明文件,来描述发布结果中的类型。

配置tsconfig.json中的declaration:true即可

  1. 手动编写
  • 对已有库,它是使用js书写而成,并且更改该库的代码为ts成本较高,可以手动编写声明文件

  • 对一些第三方库,它们使用js书写而成,并且这些第三方库没有提供声明文件,可以手动编写声明文件。

  1. 全局声明

声明一些全局的对象、属性、变量。

namespace: 表示命名空间,可以将其认为是一个对象,命名空间中的内容,必须通过命名空间.成员名访问。

  • admin.d.ts
// admin.d.ts
declare module 'adminServer' {
    export interface LoginVO {
        firstLogin?: boolean // 注释:是否首次登陆
        menuSelectVoList?: any // 注释:菜单列表
        token?: string // 注释:登录凭证
        userNameVO?: UserNameVO // 注释:用户信息
    }
}


  • service.ts
// service.ts 使用
import * as IntrefaceModel from 'adminServer'

// 当前用户
export const getCurrentUserV1 = (param?: any): Promise<IntrefaceModel.LoginVO> => {
    return api.post(`/get-current-user/v1`, param)
}
  1. 模块声明:三斜线指令

在一个声明文件中,包含另一个声明文件。

发布

  1. 当前工程使用ts开发

编译完成后,将编译结果所在文件夹直接发布到npm上即可

  1. 为其他第三方库开发的声明文件

发布到@types/**中。

1) 进入github的开源项目:github.com/DefinitelyT…

2) fork到自己的开源库中

3) 从自己的开源库中克隆到本地

4) 本地新建分支(例如:mylodash4.3),在新分支中进行声明文件的开发

在types目录中新建文件夹,在新的文件夹中开发声明文件

5) push分支到你的开源库

6) 到官方的开源库中,提交pull request

7) 等待官方管理员审核(1天)

审核通过之后,会将你的分支代码合并到主分支,然后发布到npm。

之后,就可以通过命令npm install @types/你发布的库名