如何在不指定类型参数的情况下使用通用接口的多种实现?

时间:2020-05-11 17:41:11

标签: typescript generics typescript-generics

说我有这个通用接口:

interface IProcessor<T>{
  process(param:T):T;
}

它是这样实现的:

interface User{
  name:string;
}

class WebProcessorImplementation implements IProcessor<User>{
  process(param: User): User {
    console.log(`process user`);
    return {
      name:"User"
    }
  }
}

如果我想使用该通用接口的数组,则会收到投诉:

class Coordinator {
  processors:IProcessor[] //Generic type 'IProcessor<T>' requires 1 type argument(s).ts(2314)
}

是否有一种方法可以告诉Typescript在这里一切正常,并且我们将向其传递此接口的完整实现,并且不需要type参数?我愿意采用其他方法来解决用例。

2 个答案:

答案 0 :(得分:0)

要对其进行编译,我们可以使用any

class Coordinator {
  processors:IProcessor<any>[]
}

但是,如果我们尝试访问<T>内部的Coordinator(如提到的@jcalz),那将无济于事。

最终将接口定义更改为此:

type Result = {data:string}
interface IProcessor{
  process():Result;
}

实施

class WebProcessorImplementation implements IProcessor{
  process(): Result {
    console.log(`process something`);
    return {
      data:"User"
    }
  }
}

class Coordinator {
  processors:IProcessor[]
}

答案 1 :(得分:0)

现在,您将其设置为IProcessor需要一个type参数,使其成为可选参数,并为其指定默认类型 即。

interface IProcessor<T = unknown>{ 
  process(param:T):T;
}

unknown将允许任何操作,如果泛型类型需要匹配某个模式,则可以至少使用扩展来强制执行该模式

interface User{
  name:string;
}

interface DetailedUser{
    name: string;
    id: number;
    admin: boolean;
}

interface IProcessor<T extends User = User>{
  process(param:T):T;
}

class Coordinator {
    processors: IProcessor[] = [] //fine
    processors1: IProcessor<{}>[] = [] //error
    processors2: IProcessor<{ name?: string}>[] = [] //error
    processors3: IProcessor<User>[] = [] // fine
    processors4: IProcessor<DetailedUser>[] = [] // also fine
}

tsplaygroud

适应性强,您始终可以直接添加类型而无需更改Iprocessor

class Coordinator {
  processors: IProcessor<User>[] = []; //assuming you want User..
}

tsPlayground

相关问题