TypeScript中泛型对象、泛型类

一. 概览

本文详细介绍泛型中泛型对象和泛型类的使用,结合实际应用场景,加深对泛型的理解、使用。

二. 泛型对象

举个例子

const test = {
    a: 1,
    b: 1
}

一个类型有没有一种可能让我么在定义的时候传入一个类似于变量的形参,在使用的时候传入具体的类型参数。在定义前不知道具体的参数类型

当然我们也可以定义为any,但是和没有限制差别不大

引入泛型对象

interface ITest<T> {
    id: Number,
    content: T,
    completed: boolean
}

const test:ITest<string> = {
    id: 1,
    content: '',
    completed: true
}

泛型实参会限制泛型形参变量的类型

作为函数的形参和实参

function createTodo<T>({
    id,
    content,
    completed
}: ITest<T>) {
    return {
        id,
        content,
        completed
    }
}

const todo1 = createTodo<string[]>({id:2, content: ['唱','跳','rap'],completed:true})

三. 泛型类

在class中,所以属性都应该是私有的,如果需要获取属性,设置属性都应该由公共的getter setter方法去完成。
完整代码


interface ITodoProps<T> {
    id: number,
    content: T;
    completed: boolean
}
    
interface ITodo<T> {
 get(): ITodoProps<T>,
 create():string
}
    
     
class Todo<T> implements ITodo<T>{
    private id: number;
    private content: T;
    private completed: boolean;
   
    constructor(id: number, content: T, completed: boolean) {
        this.id = id;
        this.content = content;
        this.completed = completed;
    }

   get(): ITodoProps<T> {
        return {
        id: this.id,
        content: this.content,
        completed: this.completed
   }}

   create(): string {
    if (typeof this.content === "string") {
      return this.createStringContent(this.content);
    } else if (Array.isArray(this.content) && typeof this.content[0] === "string") {
      return this.createArrayContent(this.content as string[]);
    } else {
      return this.createObjectContent(this.content);
    }
   }

    private createStringContent(content: string): string {
     return content
    }
    private  createArrayContent(content: string[]): string {
     return content.join(',')
    }

    private createObjectContent(content: T): string {
      let _content = '';
      for (let key in content) {
        let _content = "";
        _content += `${key}: ${content[key]}`
      }
      return _content
    }
}
    
    const todo11 = new Todo<string[]>(2,['逛街','打球','看电影'],false)
    const todo12= new Todo<{[key:string]:number}>(3, {sleep:1,walking:2,study:3},false)
    
    const todoString111 =todo11.create()
    const todoString112=todo12.create()
    
    const todoList = [todoString111,todoString112]
    const todo1 = todo11.get()
    const todo2 = todo12.get()
    
    function getTodoProp<T, K extends keyof T>(todo: T,key: K) {
       return todo[key]
    }
    
    getTodoProp(todo1,'id')

可以结合例子,去看泛型类的使用

keyof的使用

 function getTodoProp<T, K extends keyof T>(todo: T,key: K) {
       return todo[key]
    }
 getTodoProp(todo1,'id')

疑问:getTodoProp(todo1,‘id’)为什么可以编译成功,不需要传T的具体类型吗?

解答:

  1. getTodoProp 函数使用了泛型和 TypeScript 的索引类型查询,可以在不使用 T 类型的情况下获取 todo 对象上的 key 属性对应的值。
  2. 在函数定义中,泛型类型参数 T 表示传入的 todo 参数的类型,而泛型类型参数 K 是具有约束条件 extends keyof T 的索引类型查询,表示必须是 T 对象的属性名之一。

当我们在调用 getTodoProp 函数时,传入了一个 todo1 对象作为 todo 参数,而 TypeScript 会根据该对象的类型自动推断 T 类型为:
{
id: number;
content: string;
}

在 getTodoProp(todo1, ‘id’) 调用中,K 类型被推断为 ‘id’,因此 key 参数的类型为 ‘id’,这个类型也符合泛型类型参数 K 的约束条件。

类似地

function getSplitValue3<E>(value: E[],type: string):string {
    return value.join(type)
}

const aa = getSplitValue3<string>(['a','b','c'],',')
const bb = getSplitValue3<number>([1,2,3],',')

可以省略为

function getSplitValue3<E>(value: E[],type: string):string {
    return value.join(type)
}

const aa = getSplitValue3(['a','b','c'],',')
const bb = getSplitValue3([1,2,3],',')

你可能感兴趣的:(TypeScript,typescript,前端,javascript)