我正在扩展一个React表(创造性地称为" table "),它接受一个通用数据数组,以及一些列配置数据,并呈现一个表。声明如下所示:
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
}
这已经在几个地方使用过了,我正在给它添加一个功能:可选的分层数据,这样我们就可以停止使用Kendo's TreeList (它非常非常有功能,但是在我们的环境中加载有点慢)。
我的问题:我想声明T,表中使用的数据类型,由类之外的人提供,可能有一个特定的属性,使该类型具有递归子类型,但不是必需的。
我试过了:
export interface ChildData<T> {
children?: (T & ChildData<T>)[]
}
export class Table<T extends ChildData<T>> extends React.Component<TableProps<T>, any> ...
这是行不通的,因为外部类没有定义一个叫做“孩子”的属性。
问题是Table2.8不喜欢它:当我在某个地方实际使用TypeScript时,它抱怨T没有实现ChildData。(我现在正在使用TS2.3编译,但我会在某个时候升级到2.4以上,真的,我发誓。最终会的。无论如何,我绝对不想被阻止升级。我知道它不能在2.8上工作,因为我的IDE使用2.8运行Intellisense,但我运行的是2.3编译器。)
我也尝试过使用联合和交集类型声明,但它们根本不能编译,即使在TS2.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,但不是必须的”?我的组件已经在其他几个地方被使用了,而且它将被不是我的人使用。我不想要求表的消费者也通过一个他们不使用的“孩子”属性来扩展他们的T类型(因为表的分层特性是完全可选的)。
发布于 2018-06-01 20:52:18
经过一番摸索之后,我终于意识到数据只在一个地方很重要:在TableStore的“ChildData”属性中,这是所有相关数据所在的地方。所以我重新定义了TableStore:
export class TableStore<T> {
public data: (T & ChildData<T>)[];
constructor(input: T[]) { this.data = input; }
}
显然,您不能在泛型参数中使用&和|,但可以使用“扩展”。而且,如果您一直传递泛型参数,TypeScript最终会失去对泛型细节的跟踪。在类中使用T并在属性中使用(T & somethingElse)的行为,允许我直接将T赋给(T & somethingElse)。
我假设,就像TypeScript 2.4收紧泛型一样,TypeScript的未来版本将不允许我目前逃脱惩罚的恶作剧。
请注意,这个实现有点不可靠,因为我必须在内部的几个地方以及在生成TableStore的数据时在消费类中强制转换为。
https://stackoverflow.com/questions/50634863
复制相似问题