首页 前端知识 TypeScript基础

TypeScript基础

2024-04-29 11:04:26 前端知识 前端哥 57 347 我要收藏

目录

基本使用

使用场景

枚举类型

any 类型

类型断言

TypeScript 泛型

泛型在函数上的应用

泛型在接口上的应用

泛型在类型别名上的应用


字面量类型:将字面量当做一个类型去使用

基本使用

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

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',就是一个字面量类型

  • 任意的 JS 字面量(比如,数字、字符串、布尔值、数组、对象、函数等)都可以作为类型使用

    • 字面量: 20 'abc' false [] { name: 'jack' } function() {}

使用场景

使用场景:字面量类型配合联合类型一起使用,表示一组明确的可选值

优点:使用字面量类型更加精确、严谨

  • 示例 1:性别的取值,只能是男或女其中的一个

type GenderType = '男' | '女'

// 赋值时,会有类型提示

let gender: GenderType = '男'

示例 2:在贪吃蛇游戏中,游戏的方向的可选值只能是上、下、左、右中的任意一个

// 使用自定义类型:

type DirectionType = 'up' | 'down' | 'left' | 'right'

function changeDirection(direction: DirectionType) {

  console.log(direction)

}

// 调用函数时,会有类型提示

changeDirection('up')

枚举类型

枚举:类似于字面量类型+联合类型组合的功能,表示一组明确的可选值

  1. 枚举既可以当做类型使用,也可以当做数据值使用

  2. 枚举既可以通过键取到值,也可以通过值取到键

// 定义枚举

enum Direction {

  Up = 'Up',

  Down = 'Down',

  Left = 'Left',

  Right = 'Right'

}

// 枚举可以当做类型使用

function changeDirection(direction: Direction) {

  console.log(direction)

}

// 枚举也可以当做数据值使用

changeDirection(Direction.Up)


 

// 枚举既可以通过键取到值,也可以通过值取到键

enum ExamineStatus {

  /* 待审核 */

  WaitExamine =  1,

  /* 审核成功 */

  ExamineSuccess = 2,

  /* 审核失败 */

  ExamineFail = 3

}

console.log(ExamineStatus.ExamineFail)

console.log(ExamineStatus[1])

注意:

  1. 使用 enum 关键字定义枚举

  2. 约定枚举名称以大写字母开头

  3. 枚举中的多个值之间通过 逗号 分隔

any 类型

any 类型:逃避 TS 的类型检查。

  • 当值的类型为 any 时,可以对该值进行任意操作,编辑器也不会报错,并且不会有代码提示。这样就会使代码出现问题的概率增大。

let temp: any = 11

temp = 'str' // 没有报错

temp.toFixed(2) // 没有提示。但浏览器执行代码时会报错

  • 原则: 不推荐使用 any! 这会让 TypeScript 变为 “AnyScript” (失去 TS 类型保护的优势)

  • 尽可能的避免使用 any 类型,但是有时候,在开发过程中,不确定类型时,可以先用 any 占位 =》确认类型后 =》再去写成具体类型

类型断言

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

需求:假设在页面上有一个 a 标签,<a id="link" href="xxx"></a> ,我们想要获取 a 标签 DOM 元素的 href 属性。

// 这种方式获取的元素,ts 不知道它是一个 a 标签。所以获取元素的 href 属性时,会报错。

const aLink = document.querySelector('#link')

console.log(aLink.href) // 报错

// ts 不知道,但是我们知道。所以要给它加上类型断言,告诉 ts 它就是一个 a 标签的元素类型

const aLink = document.querySelector('#link') as HTMLAnchorElement

console.log(aLink.href)

// 想要知道一个 html 元素的具体类型,可以创建该元素,然后使用鼠标悬停去摸一摸

const a = document.createElement('a')

TypeScript 泛型

泛型:可以将类型当做参数传递,从而实现复用。常用于:函数、接口、类型别名中。

泛型在函数上的应用

泛型函数:函数可以配合泛型来使用,以增加其灵活性和复用性。

需求:给 sayHi 函数传入打招呼的名字,并将该名字返回。(也就是说,参数和返回值类型相同)

// JS 通过函数传参,达到数据的复用

const sayHi1 = () => {

  console.log('hello zs');

  return 'zs'

}

const sayHi2 = () => {

  console.log('hello ls');

  return 'ls'

}

const sayHi = (name: string): string => {

  console.log('hello' + name);

  return name

}

sayHi('zs')

sayHi('ls')


 

// TS 通过类型传参,达到类型复用

// 不使用泛型

const sayHi1 = (name: string): string => {

  console.log('hello' + name);

  return name

}

sayHi1('zhangsan')

const sayHi2 = (name: number): number => {

  console.log('hello' + name);

  return name

}

sayHi2(9527)

// 使用泛型

const sayHi = <T>(name: T): T => {

  console.log('hello' + name);

  return name

}

sayHi<string>('zhangsan')

sayHi<number>(9527)

泛型在接口上的应用

泛型接口:接口也可以配合泛型来使用,以增加其灵活性和复用性。

// 不使用泛型

interface MyObj1 {

  name: string,

  sayHi(): string

}

const obj1: MyObj1 = {

  name: 'zs',

  sayHi() {

    console.log('Hi,', this.name)

    return this.name

  }

}

interface MyObj2 {

  name: number,

  sayHi(): number

}

const obj2: MyObj2 = {

  name: 9527,

  sayHi() {

    console.log('Hi,', this.name)

    return this.name

  }

}

// 使用泛型

interface IMyObj<T> {

  name: T,

  sayHi(): T

}

const obj1: IMyObj<string> = {

  name: 'zs',

  sayHi() {

    console.log('Hi,', this.name)

    return this.name

  }

}

const obj2: IMyObj<number> = {

  name: 9527,

  sayHi() {

    console.log('Hi,', this.name)

    return this.name

  }

}

内置的泛型接口:

const arr: Array<string> = ['a', 'b', 'c']

arr.push('d', 'e')

技巧:可以通过 ctrl + 鼠标左键(Mac:command + 鼠标左键)来查看具体的类型信息

泛型在类型别名上的应用

泛型别名:类型别名也可以配合泛型来使用,以增加其灵活性和复用性。

需求:对后端返回的数据进行类型定义。

// 后端返回的数据

// const res = await getUserInfo()

// 用户信息

let res1 = {

  msg: '操作成功',

  code: 10000,

  data: {

    name: 'zhangsan',

    age: 18

  }

}

// 商品信息

let res2 = {

  msg: '操作成功',

  code: 10000,

  data: {

    id: 10001,

    goodsName: '苹果'

  }

}

// 定义后端返回的数据的类型

// 不使用泛型

type UserData = {

  msg: string;

  code: number;

  data: {

    name: string;

    age: number;

  }

}

let res1: UserData = {

  msg: '操作成功',

  code: 10000,

  data: {

    name: 'zhangsan',

    age: 18

  }

}

type GoodsData = {

  msg: string;

  code: number;

  data: {

    id: number;

    goodsName: string;

  }

}

let res2: GoodsData = {

  msg: '操作成功',

  code: 10000,

  data: {

    id: 10001,

    goodsName: '苹果'

  }

}

// 使用泛型

type Data<T> = {

  msg: string;

  code: number;

  data: T

}

type UserData = {

  name: string;

  age: number;

}

type GoodsData = {

  id: number;

  goodsName: string;

}

let res1: Data<UserData> = {

  msg: '操作成功',

  code: 10000,

  data: {

    name: 'zhangsan',

    age: 18

  }

}

let res2: Data<GoodsData> = {

  msg: '操作成功',

  code: 10000,

  data: {

    id: 10001,

    goodsName: '苹果'

  }

}

转载请注明出处或者链接地址:https://www.qianduange.cn//article/6317.html
标签
评论
发布的文章

HTML5 多人游戏开发(二)

2024-07-20 17:07:44

web前端(第一天HTML)

2024-07-20 17:07:16

HTML 音频(Audio)

2024-07-20 17:07:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!