我有一个用于获取数据的通用联合类型,名为RemoteData
,为此我试图创建一个更高阶的组件:
export interface IWithRemote<T> {
remote: RemoteData<T>;
}
export interface IWithData<T> {
data: T;
}
export function withRemoteData<T, K extends IWithData<T>>(XComponent: React.ComponentType<K>) {
return class extends React.Component<IWithRemote<T>> {
render() {
const { remote } = this.props;
switch (remote.kind) {
case RemoteDataKind.NotAsked:
return <div> nice not asked yet </div>;
case RemoteDataKind.Loading:
return <Spinner />;
case RemoteDataKind.Success:
return <XComponent data={remote.data} />
case RemoteDataKind.Failure:
return <div>daaaamn</div>;
default:
return assertNever(remote);
}
}
};
}
但是这些类型不起作用。不确定我是否正在尝试做的事情,无论如何我都会得到
TS2322:键入'{data:T; }”不能分配给类型“ K”。
当我尝试将remote.data
分配给data
的{{1}}时。
Here,您会找到重现该问题所需的所有代码。有没有办法解决这些类型?
答案 0 :(得分:1)
您可以简单地
export function withRemoteData<T>(
XComponent: React.ComponentType<IWithData<T>>
) {
return class extends React.Component<IWithRemote<T>> {
render() {
const { remote } = this.props;
switch (remote.kind) {
case RemoteDataKind.NotAsked:
return <div> nice not asked yet </div>;
case RemoteDataKind.Loading:
return <div> spinnnnnner </div>;
case RemoteDataKind.Success:
return <XComponent data={remote.data} />;
case RemoteDataKind.Failure:
return <div>daaaamn</div>;
default:
return assertNever(remote);
}
}
};
}
答案 1 :(得分:1)
HOC的参数类型z<=64
期望其属性符合某种类型的XComponent
,该类型可能包含K
之外的一些其他属性。
但是,HOC的data
类型props
具有IWithRemote<T>
属性,当remote
为{{1}时,该属性声明为仅具有data
},没什么。
因此,当您使用
渲染kind
时
Success
XComponent
预期从其<XComponent data={remote.data} />
接收的K
中所有其他属性应该来自哪里?
无论如何,如果XComponent
为props
时XComponent
所需的所有内容与data
中的remote
一起出现,则可以声明确实如此-您只需将kind
参数添加到Success
和K
,然后将RemoteData
联合成员声明为交集类型
IWithRemote
完整的类型是
Success
然后,在渲染 {
kind: RemoteDataKind.Success;
} & K
时,需要确保type RemoteData<T, K extends IWithData<T>> =
| {
kind: RemoteDataKind.NotAsked;
}
| {
kind: RemoteDataKind.Loading;
}
| {
kind: RemoteDataKind.Success;
} & K
| {
kind: RemoteDataKind.Failure;
error: Error;
};
interface IWithRemote<T, K extends IWithData<T>> {
remote: RemoteData<T, K>;
}
interface IWithData<T> {
data: T;
}
export function withRemoteData<T, K extends IWithData<T>>(
XComponent: React.ComponentType<K>
) {
return class extends React.Component<IWithRemote<T, K>> {
中的所有内容都传递给它,而不仅仅是XComponent
:
remote