半天入门 TypeScript (下)

126 阅读5分钟

23.枚举

枚举(enum)的功能类似于字面量类型+联合类型组合的功能,来描述一个值,该值只能是 一组命名常量 中的一个

enum 枚举名 { 可取值1, 可取值2,.. }

  1. 使用 enum 关键字定义枚举
  2. 一般约定首字符大写
  3. 枚举中的多个值之间通过 ,(逗号)分隔
  4. 定义好枚举后,直接使用枚举名称作为类型注解
// 定义枚举类型
enum Direction { Up, Down, Left, Right }

// 使用枚举类型
function changeDirection(direction: Direction) {
  console.log(direction)
}

// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Up)



//枚举的第二中写法====>配合联合类型
// type定义的类型是没有值的 - 不能console.log
type NewType = number | string
console.log(NewType)  // 输出类型是没有意义的

// 创建枚举
enum Direction { Up, Down, Left, Right }

// 枚举是有值的 - 可以console.log
console.log(Direction.Up)




//枚举的第三中写法===>数字枚举

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

enum Direction { Up = 2, Down = 3, Left = 8, Right = 16 }



//枚举的第四中写法===>字符串枚举
enum Direction {
  Up = 'UP',
  Down = 'DOWN',
  Left = 'LEFT',
  Right = 'RIGHT'
}

24.枚举类型的应用场景

注意这里的girl默认为0, boy默认为1 也可以将属性赋值number类型的值不会报错

enum Gender {
      girl,
      boy
}
type User = {
     name: string,
     gender: Gender
}

const u1: User = {
     name: '小花',
     gender: Gender.girl // 写代码的时候,可以利用代码提示
}

console.log(u1)

25.any 类型

any: 任意的。当类型设置为 any 时,就取消了类型的限制。就等于没有开启ts模式

临时使用any 来“避免”书写很长、很复杂的类型

let obj: any = { x: 0 }

obj.bar = 100
obj()
const n: number = obj

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


26.类型断言

什么是类型断言?

断言就是表示肯定,假设我知道是某个属性类型,我就可以肯定你是这个属性

用法

const 变量 = 值 as 类型

const box = document.getElementById('img') as HTMLImageElement
//如上操作表示我肯定你是HTMLImageElement
box.src



type User = {
  name: string,
  age: number
}

const u1 = {} as User

console.log(u1.name) // 这里就会有提示

27.typeof

根据已有的变量来推断数据类型,减少书写错误

type 类型 = typeof 常量

const res= { name: '小花', city: '武汉',  skills: ['js', 'css'] }
typeof Sun = res
function fn(obj:Stu) {
    // 这里写 obj. 就会有提示
    
}

fn(res)

28.keyof

用来获取某个对象/类型的 属性名 来构成新类型

type 类型 = keyof 类型

type 类型 = keyof 对象常量

const ref={x:number,y:number}
type P= keyof ref
type O= keyof {name:'jack',age:18}

29.泛型(重点)

泛型,顾名思义,就是可以适用于多个类型,使用类型变量(比如T)帮助我们捕获传入的类型,之后我们就可以继续使用这个类型。React大多数内置方法都是用泛型写的。

本质是参数化类型,通俗的讲,就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和函数的创建中,分别成为泛型类泛型接口泛型函数

泛型函数: 这个函数的参数类型或者返回值的类型可变的

function 函数名<类型变量1,类型变量2,...>(参数1:类型1,参数2:类型2,...): 返回值类型 {}

function fn<Type>(value: Type): Type { return value }
// 上面的Type只是一个名字而已,可以改成其他的,例如T

function fn<T>(value: T): T { return value }

const 返回值 = 泛型函数名<类型1,类型2,...>(实参1,实参2,实参3,......)

const num = fn<number>(10)
const str = fn<string>('a')
function fn<T>(value: T): T {
  // 这里value. 不会有提示
  console.log(value.length)// 这里会报错
  return value
}

fn('a')

30.泛型-泛型约束

默认情况下,泛型函数的类型变量 T 可以代表多个类型,这导致在泛型函数内部无法访问任何属性

注意下面这个传入的有可能为number或者null等没有length所以这里就会报错

function fn<T>(value: T): T {
  // 这里value. 不会有提示
  console.log(value.length)// 这里会报错
  return value
}

fn('a')

31.指定更加具体的类型

function fn<T>(value: T[]): T[] {
  console.log(value.length) // 这里就可以获得提示
  return value
}

32.泛型-泛型接口

interface 接口名<类型变量1,类型变量2...> {属性名1:类型1,属性名2:类型2,属性名3:类型3}

  1. 创建描述约束的接口 ILength,该接口要求提供 length 属性
  2. 通过 extends 关键字使用该接口,为泛型(类型变量)添加约束
  3. T extends ILength约束表示:传入的类型必须具有 length 属性
// 创建一个接口
interface ILength { length: number }



// 类型参数继承接口
// T extends ILength 添加泛型约束
function fn<T extends ILength>(value: T): T {
  console.log(value.length)
  return value
}

fn('abc') // Ok
fn([1,2,3]) // Ok
interface MyArray {
  length: number,
  push(n: number):void,
  pop():number,
  reverse():number[]
}

let obj: MyArray = {
  id(value) { return value },
  ids() { return [1, 3, 5] }
}

33.泛型-典型应用

  1. 创建一个Type类型,再创建一个Key类型 ,再将Type类型的属性利用extends继承到Key中
  2. 通过obj[key]就可以实现不然则会报错
function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key]
}
let person = { name: 'jack', age: 18 }
getProp(person, 'name')



// Type extends object 表示: Type 应该是一个对象类型,如果不是 对象 类型,就会报错
// 如果要用到 对象 类型,应该用 object ,而不是 Object
function getProperty<Type extends object, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key]
}

getProperty({a:1, b:2}, 'a')

34.泛型工具类型

泛型工具类型:TS 内置了一些常用的工具类型,来简化 TS 中的一些常见操作

说明:它们都是基于泛型实现的(泛型适用于多种类型,更加通用),并且是内置的,可以直接在代码中使用。 这些工具类型有很多,先来学习以下3个:

  1. Partial<Type>
  2. Readonly<Type>
  3. Pick<Type, Keys>
1.Partial  // 可传可不传
type Props =  {
  id: string
  children: number[]
}

type PartialProps = Partial<Props>
2.Readonly  //不能修改里面的值
let props: ReadonlyProps = { id: '1', children: [] }
// 错误演示
props.id = '2'

3.Pick

3.从中挑一个类型过
type Props = { id: stringtitle: stringchildren: number[]}
// 新类型 PickProps,只有 id 和 title 两个属性类型。
type PickProps = Pick<Props, 'id' | 'title'>