javascript 如何根据当前函数参数Typescript确定返回函数的参数是否为必选项?

insrf1ej  于 2023-05-27  发布在  Java
关注(0)|答案(2)|浏览(299)

我是Typescript的新手,试图以更低的规模模仿样式化组件。在我的例子中,如果user在createStyledComponent for children参数中传递了true,我想使children成为必需的,否则使children成为可选的。
我有一个新手解决我的问题,我返回2个不同的函数,一个是必需的孩子,另一个是可选的。
有没有更好更简洁的方法来完成这项任务?

const createStyledComponent = (
    type: any,
    component_style: CSSProperties | undefined,
    children?: boolean
) => {
    if (children) {
        const returnComponent = ({
            children,
            style,
        }: {
            children: any;
            style?: CSSProperties | undefined;
        }) => {
            return React.createElement(
                type,
                { style: { ...component_style, ...style } },
                children
            );
        };
        return returnComponent;
    } else {
        const returnComponent = ({
            children,
            style,
        }: {
            children?: any;
            style?: CSSProperties | undefined;
        }) => {
            return React.createElement(
                type,
                { style: { ...component_style, ...style } },
                children
            );
        };
        return returnComponent;
    }
};
iqxoj9l9

iqxoj9l91#

我可能会诚实地尝试一下泛型。https://www.typescriptlang.org/docs/handbook/2/generics.html
以下内容可能适用于您的用例。

type StyledProps<C extends boolean> = {
    style?: CSSProperties;
    children: C extends true ? ReactNode : ReactNode | undefined;
};

const createStyledComponent = <C extends boolean>(
    type: any,
    component_style?: CSSProperties,
    childrenRequired: C = false as C
) => {
    const returnComponent = ({ children, style }: StyledProps<C>) => {
        return React.createElement(
            type,
            { style: { ...component_style, ...style } },
            children
        );
    };
    return returnComponent;
};

但是您的实现细节可能会有所不同。我肯定会偏离大的如果,否则渲染块是大致相同的。在这种情况下,将这些块抽象为单独的组件或执行内联条件语句会很有帮助

return (
    <div>
        {/* other shared render logic */}
        {value === true && (
            <div>value true render</div>
        )}
        {value === false && (
            <div>value false render</div>
        )}
    </div>
)

祝你好运!

hi3rlvi2

hi3rlvi22#

您需要函数重载。
这里有两个签名:
其中需要children

function createStyledComponent(
  type: any,
  component_style: CSSProperties | undefined,
  children: true, // explicit true
): (
  props: { children: React.ReactNode, style?: CSSProperties }
) => React.ReactNode

一个是他们不在的地方:

function createStyledComponent(
  type: any,
  component_style: CSSProperties | undefined,
  children?: false // missing or explicit false
): (
  props: { children?: React.ReactNode, style?: CSSProperties }
) => React.ReactNode

然后,您可以编写如下实现:

function createStyledComponent(
    type: any,
    component_style: CSSProperties | undefined,
    // children parameter here is not actually required,
    // since the implementation is identical
): (
  props: { children?: React.ReactNode, style?: CSSProperties }
) => React.ReactNode {
    const returnComponent = ({
        children,
        style,
    }: {
        children?: React.ReactNode;
        style?: CSSProperties | undefined;
    }) => {
        return React.createElement(
            type,
            { style: { ...component_style, ...style } },
            children
        );
    };
    return returnComponent;
};

请注意,函数的children参数在实现中消失了。它在运行时没有用处,因为逻辑是相同的,但它允许我们给予类型系统一个提示并强制执行所需的内容。
现在来测试一下:

createStyledComponent('div', undefined)({}) // fine
createStyledComponent('div', undefined)({ children: <></> }) // fine

createStyledComponent('div', undefined, true)({ children: <></> }) // fine
createStyledComponent('div', undefined, true)({}) // error as expected, no children

见操场

相关问题