我有一个抽象类,在该方法中传递一个泛型类型的项。接下来,我需要得到这个项目的属性,如何正确地做它?
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); }