reactjs - Typescript: Kết hợp HOCs bao bọc các component với defaultProps trong React
Cố gắng kết hợp nhiều HOC (bằng hàm compose) dường như làm mất hoàn toàn các chú thích props, như thể việc tạo một HOC đúng cách mà không làm mất các props mặc định (do đó là tùy chọn) của component được bao bọc đã không đủ khó khăn.
Đã tìm thấy một số cách khắc phục tốt để làm cho HOC giữ các props tùy chọn của các component được đóng gói bằng cách tận dụng alias JSX.LibraryManagedAttributes:
import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// wrapper
export interface WithThemeProps {
theme: string;
}
interface WrapperProps {
foo: string;
}
function withTheme<
C extends React.ComponentType<React.ComponentProps<C> & WithThemeProps>,
ResolvedProps = JSX.LibraryManagedAttributes<C, Omit<React.ComponentProps<C>, keyof WithThemeProps>>
>(component: C) {
return connect<WithThemeProps, void, WrapperProps & ResolvedProps>(() => ({
theme: 'theme',
}))(component as React.ComponentType);
}
// component with default props
interface Props extends WithThemeProps {
message: string;
required: string;
}
class Component extends React.Component<Props> {
static defaultProps = {
message: '',
};
render() {
return <div />;
}
}
// usage
const Wrapped = withTheme(Component);
const el = <Wrapped required="r" foo="f" />; // works
const Composed = compose(withTheme)(Component);
const HeavilyComposed = compose( withTheme, withTheme )(Component);
const x = <Composed required="r" foo="f" />; // wrapped works
const y = <HeavilyComposed required="r" foo="f" />; // error, props are lost altogether
Ngoài ra, tôi tình cờ gặp một ý tưởng thú vị để mô hình hóa hàm compose cho kịch bản cụ thể này. Với một chút chỉnh sửa từ câu trả lời gốc, tất cả các props đều được giữ nguyên, nhưng đồng thời nó cũng làm chúng trở nên bắt buộc, điều mà tôi không mong đợi:
const HeavilyComposed = compose( withTheme, withTheme )(Component);
// Type '{ required: string; foo: string; }' is missing the
// following properties from type 'Props': message, theme
const y = <HeavilyComposed required="r" foo="f" />;
declare function compose<A, R, R2>(
f1: (b: A) => React.ComponentType<R2>,
f2: (b: A) => React.ComponentType<R>
): <P>(c: React.ComponentType<P>) => React.ComponentType<P & R & R2>;
Một hàm compose nên trông như thế nào để giữ nguyên các props tùy chọn và bị bỏ qua?