我正在扩展一个React表(创造性地称为“表”),该表采用通用数据数组以及一些列配置数据,并呈现表。声明如下:
export class Table<T> extends React.Component<TableProps<T>, any>
TableProps的非可选部分:
export interface TableProps<T> {
columnConfigs: TableColumnConfig<T>;
tableStore: TableStore<T>;
}
TableStore只有一个必需属性:
export class TableStore<T> {
public data: T[];
}
TableColumnConfigs并不是非常重要,因为T仅用于可选属性:
export interface TableColumnConfigs<T> {
render?: (data: T) => JSX.Element
}
此&lt;表&gt;已经使用了几个地方,我正在添加一个功能:可选的分层数据,所以我们可以停止使用Kendo's TreeList(这是非常非常有用的,但在我们的环境中加载有点慢)。
我的问题:我想声明T,表中使用的数据类型,由类外的人提供,可能具有特定属性, type有递归子,但不是必需的。
我试过这个:
export interface ChildData<T> {
children?: (T & ChildData<T>)[]
}
export class Table<T extends ChildData<T>> extends React.Component<TableProps<T>, any> ...
这不起作用,因为外部类没有定义名为“children”的属性。
问题在于TypeScript 2.8不喜欢它:当我实际在某处使用Table时,它会谴责T没有实现ChildData。 (我现在正在使用TS 2.3进行编译,但我会升级到2.4,在某些时候,很快就会发生,我发誓。最终。无论如何,我绝对不希望被阻止< / em>来自升级。我知道它在2.8上不起作用,因为我的IDE使用2.8运行Intellisense,但我正在运行2.3编译器。)
我也尝试使用union和intersection类型声明,但它们根本无法编译,即使在TS 2.3下:
export class Table<T & ChildData<T>> extends React.Component<TableProps<T>, any> ...
export class Table<T | ChildData<T>> extends React.Component<TableProps<T>, any> ...
有没有办法说“我有一个通用参数T,可以实现一个ChildData,但不是必须的?”我的&lt;表&gt;组件已经在其他地方的几个地方使用,并且它将由不是我的人使用。我不希望要求Table的使用者也通过他们没有使用的“children”属性来扩展他们的T类型(因为表的层次结构特征是完全可选的)。
答案 0 :(得分:0)
在经历了一些困难之后,我终于意识到ChildData只在一个地方很重要:在&#34;数据&#34; TableStore的属性,它是所有相关数据的所在。所以我重新定义了TableStore:
export class TableStore<T> {
public data: (T & ChildData<T>)[];
constructor(input: T[]) { this.data = input; }
}
显然,你不能使用&amp;和|在通用参数中,但是&#34;扩展&#34;没关系。而且,如果你不断传递泛型参数,TypeScript最终会失去对泛型的精细细节的追踪。在类中使用T并在属性中使用(T&amp; somethingElse)的行为允许我直接将T分配给(T&amp; somethingElse)。
我假设,就像TypeScript 2.4收紧泛型一样,未来的TypeScript版本将禁止我目前正在逃避的诡计。
请注意,实施有点不稳定,因为我必须转向&lt; T&amp; ChildData&LT; T&GT;&GT;在&lt; Table&gt;内的几个地方,以及在消费类中我生成TableStore的数据。