reactjs - redux 的类型 / 像装饰器一样连接
问题描述
我正在尝试创建一个装饰器,其行为类似于 redux 的connect
装饰器:在装饰组件中注入一些额外的道具。我的打字有问题
额外的.d.ts
export interface ExtraProps {
extra: string;
}
// problem must be with this. Intent is to "add" the "extra" prop
// and not require it when the user actually renders it.
export function extra<P>(): (
Comp: ComponentType<P & ExtraProps>
) => ComponentType<P>;
样本.tsx
interface MyCompProps extends ExtraProps {
notSoExtra: string;
}
class MyComp extends React.Component<MyCompProps> {
render() {
console.log(this.props.extra, this.props.notSoExtra); // ok
return null;
}
}
// Decorating it here, prop types should be { notSoExtra: string }
const MyCompWithExtra = extra()(MyComp);
class App extends React.Component {
render() {
return <MyCompWithExtra notSoExtra="boring prop" />;
// error ^^^^^^
}
}
因此,在渲染时MyCompWithExtra
出现错误:
[ts] 类型 '{ notSoExtra: string; }' 与类型 'IntrinsicAttributes & { children?: ReactNode; 没有共同的属性。}'。
此外,当我像这样明确指定道具类型时:
const MyCompWithExtra = extra<MyCompProps>()(MyComp);
我在渲染时遇到不同的错误
[ts] 类型 '{ notSoExtra: string; }' 不可分配给类型 'IntrinsicAttributes & MyCompProps & { children?: ReactNode; }'。
键入'{ notSoExtra:字符串;}' 不可分配给类型 'MyCompProps'。'{ notSoExtra: string; 类型中缺少属性 'extra' }'。
如何以某种方式键入装饰器,以便在渲染装饰组件时可以省略道具?
解决方案
第一个问题是,如果您P
在函数中指定参数extra
,而推断它所需的信息将在返回的函数调用中指定,编译器将无法推断P
。
您可以使用单个函数,或者,如果您想指定其他参数,您可以从 extra 返回一个泛型函数。
但更大的问题是,这P & ExtraProps
并不意味着 in 中的属性ExtraProps
不会包含在P
. P
将包含所有属性,并且& ExtraProps
更多地作为对这些属性类型的约束。
要创建从另一种类型中排除属性的类型,您可以使用 的组合Pick
从类型中选择特定属性,并从 的键中Exclude<keyof A, keyof B>
排除 的键。B
A
export interface ExtraProps {
extra: string;
}
export function extra<P extends ExtraProps>(
Comp: ComponentType<P>
) : ComponentType<Pick<P, Exclude<keyof P, keyof ExtraProps>>> {
return null as any;
}
//Usage
interface MyCompProps extends ExtraProps {
notSoExtra: string;
}
class MyComp extends React.Component<MyCompProps> {
render() {
console.log(this.props.extra, this.props.notSoExtra); // ok
return null;
}
}
const MyCompWithExtra = extra(MyComp);
let s = <MyCompWithExtra notSoExtra="boring prop" />;
注意如果您希望允许用户有选择地指定extra
,您可以ComponentType<Pick<P, Exclude<keyof P, keyof ExtraProps>>> & Partial<ExtraProps>
改为返回。
推荐阅读
- javascript - 命名数组中求最小值的新方法
- rxjs - 角度 5,subject.next(value) 不会触发
- c# - GetSecurityInfo 总是返回拒绝访问
- android - 全新安装 Android Studio 后 Gradle 无法同步
- desktop-bridge - OCX control not loading into IDC_Explorer Web control;
- matlab - 为什么我的传输函数总是返回“logsig”?
- jenkins - 如何从 Kubernetes 的一次性进程中获取文件?
- amazon-web-services - Terraform:如何在项目之间迁移状态?
- java - 如何使用 Spring Boot 向 http2 微服务发出 post 请求?
- python - CSV 中的数据管理