如何获得泛型类型的属性?

Gre*_*176 8 generics typescript

我有一个抽象类,在我传递泛型类的项的方法中.接下来,我需要获取此项的属性,如何正确执行?

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> {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

Alu*_*dad 11

您的代码假定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);
    }
  }
} 
Run Code Online (Sandbox Code Playgroud)

在这里,我们定义了一个接口,使代码更具可读性,但类型文字也可以.

请注意,该id属性声明为可选属性,因为您的逻辑不要求它具有值.

如果您只打算将bass类与类型参数一起使用,id那么您应该使该属性成为必需属性.这将使代码更容易理解,并且在编译时将通过确保它仅首先与这些类型一起使用来捕获更多错误.

Shahbaaz在评论中询问动态属性.

我们可以使用参数泛型类型定义具有动态属性的类型

type WithProperty<K extends string, V = {}> = {
  [P in K]: V
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用这种类型

function withProperty<T, K extends string, V> (x: T, properties: WithProperty<K, V>) {
  return Object.assign(x, properties);
}
Run Code Online (Sandbox Code Playgroud)