类型中的属性不能分配给基类型中的相同属性

时间:2021-03-25 16:50:51

标签: typescript typescript-generics

嗨,我有一个基本示例,我不断收到此错误,但我不确定到底是什么问题。

基本上我想在运行时将不同类型传递给 class A。在给定的示例中,它是 Order,但我将为 ProductCustomers 等编写其他类,并且对于所有这些类,我想使用 A<T> 作为父类。我还在最小的例子下面添加了真正的代码。

请有人解释解决方案和问题。

interface Order{
    customer: {
        name: string;
    };
}

abstract class A<T>{
    protected abstract matches<T>(tableData: T, term: string): boolean;
}

class B extends A<Order>{

    protected matches<T extends Order>(tableData: T, term: string): boolean {
        return tableData.customer.name.toLowerCase().includes(term.toLowerCase());
    }
}

目标是在 tableData.customer 内访问 class B。我想将 Order 作为泛型类型传递给 matches 方法,但我不确定如何以正确的方式实现这一点。

更新

父类:

export abstract class TableFilterService<T> {
  private _loading$ = new BehaviorSubject<boolean>(true);
  private _search$ = new Subject<void>();
  private _total$ = new BehaviorSubject<number>(0);
  private _tableData$: BehaviorSubject<T[]> = new BehaviorSubject([]);
  private _data$!: T[];

  protected _state: State = {
    page: 1,
    pageSize: 50,
    searchTerm: '',
    sortColumn: '',
    sortDirection: ''
  };

  private compare = (v1: string | number, v2: string | number) => v1 < v2 ? -1 : v1 > v2 ? 1 : 0;
  protected abstract matches<T>(tableData: T, term: string, pipe: PipeTransform): boolean;

  get tableData$() { return this._tableData$.asObservable(); }
  get search$() { return this._search$.asObservable(); }
  get total$() { return this._total$.asObservable(); }
  get loading$() { return this._loading$.asObservable(); }
  get page() { return this._state.page; }
  get pageSize() { return this._state.pageSize; }
  get searchTerm() { return this._state.searchTerm; }
  get data() { return this._data$; }

  set data(data: T[]) { this._data$ = data; }
  set page(page: number) { this._set({page}); }
  set pageSize(pageSize: number) { this._set({pageSize}); }
  set searchTerm(searchTerm: string) { this._set({searchTerm}); }
  set sortColumn(sortColumn: SortColumn) { this._set({sortColumn}); }
  set sortDirection(sortDirection: SortDirection) { this._set({sortDirection}); }

  constructor(protected pipe: DecimalPipe) {

    this._search$.pipe(
      tap(() => this._loading$.next(true)),
      debounceTime(200),
      switchMap(() => this._search()),
      delay(200),
      tap(() => this._loading$.next(false))
    ).subscribe(result => {
      this._tableData$.next(result.tableData);
      this._total$.next(result.total);
    });

    this._search$.next();
  }

  protected sort<T>(orders: T[], column: SortColumn, direction: string): T[] {
    if (direction === '' || column === '') {
      return orders;
    } else {
      return [...orders].sort((a: any, b: any) => {
        const res = this.compare(a[column], b[column]);
        return direction === 'asc' ? res : -res;
      });
    }
  }

  protected _search(): Observable<SearchResult<T>> {
    const {sortColumn, sortDirection, pageSize, page, searchTerm} = this._state;

    // 1. sort
    let tableData = this.sort(this.data, sortColumn, sortDirection);

    // 2. filter
    tableData = tableData.filter(data => this.matches(data, searchTerm, this.pipe));
    const total = tableData.length;

    // 3. paginate
    tableData = tableData.slice((page - 1) * pageSize, (page - 1) * pageSize + pageSize);

    return of({ tableData, total});
  }

  private _set(patch: Partial<State>) {
    Object.assign(this._state, patch);
    this._search$.next();
  }
}

子类:

export class OrderTableService extends TableFilterService<Order>{

  protected matches(tableData: Order, term: string, pipe: PipeTransform): boolean {
    return tableData.customer.name.toLowerCase().includes(term.toLowerCase());
  }
}

错误:

enter image description here

完整的错误:

Property 'matches' in type 'OrderTableService' is not assignable to the same property in base type 'TableFilterService<Order>'. Type '(tableData: Order, term: string, pipe: PipeTransform) => boolean' is not assignable to type '<T>(tableData: T, term: string, pipe: PipeTransform) => boolean'. Types of parameters 'tableData' and 'tableData' are incompatible. Type 'T' is not assignable to type 'Order'.ts

1 个答案:

答案 0 :(得分:1)

您的抽象函数泛型 CultureInfo 覆盖了类 matches<T> 的泛型 T。你写的基本上是这样的:

A<T>

类顶部的泛型 abstract class A<T>{ protected abstract matches<U>(tableData: U, term: string): boolean; } 基本上没有用。解决方案可能类似于 this:

T
相关问题