简体   繁体   English

typescript generics class,方法参数和方法返回类型

[英]typescript generics class, method parameter and method return type

I have this function我有这个 function

function getCollection<T>(collectionType: T): Collection<T> {
  return new Collection<T>()
}

and in Collection class I have thisCollection class 中我有这个

export class Collection<T> {
  public add (item: T) {
    // .. logic
  }
}

I have a user class defined like this我有一个这样定义的用户 class

export class Student {

}

and when I attempt to do当我尝试做

getCollection(Student).add(new Student());

There is an error有一个错误

TS2345: Argument of type 'Student' is not assignable to parameter of type 'typeof Student'. TS2345:“Student”类型的参数不可分配给“typeof Student”类型的参数。 Property 'prototype' is missing in type 'Student' but required in type 'typeof Student'. “Student”类型中缺少属性“prototype”,但在“typeof Student”类型中是必需的。

Following works fine.以下工作正常。

new Collection<Student>().add( new Student());

So what is wrong when the function returns generic collection?那么当 function 返回泛型集合时出了什么问题呢?

T is actually of type typeof Student . T实际上是typeof Student类型。 Student is an instance of the class, while typeof Student is the constructor. Student是 class 的实例,而typeof Student是构造函数。 To get the instance type of a constructor, use the intuitively named InstanceType built-in:要获取构造函数的实例类型,请使用直观命名的InstanceType内置函数:

public getCollection<T>(collectionType: T): Collection<InstanceType<T>> {
  return new Collection<InstanceType<T>>("some-arg1", "some-arg2")
}

But now you have to add a constraint which shouldn't be too much of a problem:但是现在你必须添加一个约束,这应该不是什么大问题:

public getCollection<T extends new (...args: any[]) => any>(...

This should result in:这应该导致:

public getCollection<T extends new (...args: any[]) => any>(collectionType: T): Collection<InstanceType<T>> {
  return new Collection<InstanceType<T>>("some-arg1", "some-arg2")
}

This error is caused due to the fact that the generic type is inferred from the parameter;这个错误是由于泛型类型是从参数推断出来的; meaning that T is not Student but it is actually typeof Student .这意味着T不是Student但它实际上是typeof Student Hence return new Collection<T> does not behave like return new Collection<Student> but is instead return new Collection<typeof Student> .因此return new Collection<T>的行为不像return new Collection<Student>而是return new Collection<typeof Student>

This can be fixed by actually assigning a type to the generic parameter:这可以通过实际为泛型参数分配一个类型来解决:

getCollection<Student>(Student)

The above makes the use of the parameter redundant, hence getCollection can be refactored to the following:上面使参数的使用变得多余,因此getCollection可以重构为以下内容:

getCollection<T>(): Collection<T> {
  return new Collection<T>("some-arg1", "some-arg2");
}

and be called as:并被称为:

getCollection<Student>()

Link to the playground .链接到游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM