我有一个抽象类,在该方法中传递一个泛型类型的项。接下来,我需要得到这个项目的属性,如何正确地做它?

export abstract class BaseService<T> {
    ...
    public saveItem(item: T) {
        ...
        if (item.id <=== here I got error ) {
        }
        ...
    }

    export class ClusterItem {
        id: number;
        ...
     }

    export class ClustersService extends BaseService<ClusterItem> {
        ...
    }

最佳答案

您的代码假设与类一起使用的每个类型T都可能有一个id属性。
正如Jon Sharpe在对您的问题的评论中指出的,正确的方法,无论是在类型安全性和表现性方面,都是将这种假设声明为类型约束,使其明确且已知类型检查器。
这样做的方法是在泛型类型参数上使用类型约束语法。
例如,你可以写

export interface MayHaveId {
  id?: number; // you can use any type, number is just an example
}

export abstract class BaseService<T extends MayHaveId> {
  saveItem(item: T) {
    if (item.id !== undefined) {
      console.log(item.id);
    }
  }
}

在这里,我们定义了一个接口,使代码更可读,但类型文字也可以工作。
注意,属性被声明为可选的,因为您的逻辑不要求它具有一个值。
如果您只希望bass类与具有id的类型参数一起使用,那么应该使属性成为必需的。这将使代码更易于理解,并且在编译时会捕获更多错误,确保它只与此类类型一起使用。
沙巴兹在评论中询问了动态特性。
我们可以通过使用参数泛型类型来定义具有动态属性的类型。
type WithProperty<K extends string, V = {}> = {
  [P in K]: V
}

我们可以消费这种类型的
function withProperty<T, K extends string, V> (x: T, properties: WithProperty<K, V>) {
  return Object.assign(x, properties);
}

10-02 02:23
查看更多