英文:
How to make the parameters of returning function required or not based on current function parameters Typescript?
问题
以下是代码的中文翻译部分:
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;
}
};
英文:
I am new to Typescript and trying to mimic styled-components at a much lower scale. In my case, I want to make children required if user passed true
in createStyledComponent for children parameter, otherwise make the children optional.
I kinda have a newbie solution to my problem where I am returning 2 different functionsm, one with required children and other with optional.
Is there a better and concise way to do this task?
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;
}
};
答案1
得分: 1
I would probably try and take a stab at generics honestly. 以下是可能适用于您的用例的示例代码。
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;
};
But your implementation details might vary. I definitely would stray away from big if, else render blocks that are largely the same. In that type of scenario it can be helpful to abstract these blocks into separate components, or do inline conditionals.
return (
<div>
{/* other shared render logic */}
{value === true && (
<div>value true render</div>
)}
{value === false && (
<div>value false render</div>
)}
</div>
)
Good luck!
英文:
I would probably try and take a stab at generics honestly. https://www.typescriptlang.org/docs/handbook/2/generics.html
Something like the following might work for your use case.
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;
};
But your implementation details might vary. I definitely would stray away from big if, else render blocks that are largely the same. In that type of scenario it can be helpful to abstract these blocks into separate components, or do inline conditionals
return (
<div>
{/* other shared render logic */}
{value === true && (
<div>value true render</div>
)}
{value === false && (
<div>value false render</div>
)}
</div>
)
Good luck!
答案2
得分: 0
以下是翻译好的内容:
你想要函数重载。
这里有两个签名:
一个要求children
:
function createStyledComponent(
type: any,
component_style: CSSProperties | undefined,
children: true, // 明确为true
): (
props: { children: React.ReactNode, style?: CSSProperties }
) => React.ReactNode
另一个不需要children
:
function createStyledComponent(
type: any,
component_style: CSSProperties | undefined,
children?: false // 缺失或明确为false
): (
props: { children?: React.ReactNode, style?: CSSProperties }
) => React.ReactNode
然后,你可以编写实现如下:
function createStyledComponent(
type: any,
component_style: CSSProperties | undefined,
// 这里的children参数实际上不是必需的,
// 因为实现是相同的
): (
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)({}) // 正常
createStyledComponent('div', undefined)({ children: <></> }) // 正常
createStyledComponent('div', undefined, true)({ children: <></> }) // 正常
createStyledComponent('div', undefined, true)({}) // 预期错误,没有children
英文:
You want function overloads.
You have two signatures here:
One where children
are required:
function createStyledComponent(
type: any,
component_style: CSSProperties | undefined,
children: true, // explicit true
): (
props: { children: React.ReactNode, style?: CSSProperties }
) => React.ReactNode
And one where they are not:
function createStyledComponent(
type: any,
component_style: CSSProperties | undefined,
children?: false // missing or explicit false
): (
props: { children?: React.ReactNode, style?: CSSProperties }
) => React.ReactNode
Then you can write the implementation as follows:
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;
};
Note that the children
parameter to your function is gone in the implementation. It has no use at runtime since the logic is identical, but it does allows us to give the type system a tip and enforce what is required.
Now to test that out:
createStyledComponent('div', undefined)({}) // fine
createStyledComponent('div', undefined)({ children: <></> }) // fine
createStyledComponent('div', undefined, true)({ children: <></> }) // fine
createStyledComponent('div', undefined, true)({}) // error as expected, no children
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论