Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用条件道具接口定义React组件?_Javascript_Reactjs_Typescript_Field_Tsx - Fatal编程技术网

Javascript 如何使用条件道具接口定义React组件?

Javascript 如何使用条件道具接口定义React组件?,javascript,reactjs,typescript,field,tsx,Javascript,Reactjs,Typescript,Field,Tsx,我需要定义呈现textarea或input的“字段”组件取决于属性multiline 我试图这样做: 从“React”导入React; 类型Props={multiline:T}&T扩展为true ? React.HTMLProps :React.HTMLProps 导出常量字段:React.FC=({multiline,…props})=>{//error here 常量元素=多行?'textarea':'input'; 返回{}}/>;//这里出错 } //用法 常数结果=( console

我需要定义呈现
textarea
input
的“字段”组件取决于属性
multiline

我试图这样做:

从“React”导入React;
类型Props={multiline:T}&T扩展为true
? React.HTMLProps
:React.HTMLProps
导出常量字段:React.FC=({multiline,…props})=>{//error here
常量元素=多行?'textarea':'input';
返回{}}/>;//这里出错
}
//用法
常数结果=(
console.log(e.target.value)}/>//此处有错误
);
但typescript提供了以下几个错误:

1 Property 'multiline' does not exist on type 'HTMLProps<HTMLInputElement> & { children?: ReactNode; }'.(2339)

2 [large error, more in playground]

3 Property 'value' does not exist on type 'EventTarget'.(2339)

1属性“multiline”在类型“HTMLProps&{children?:ReactNode;}”上不存在。(2339)
2[误差大,操场上更多]
3类型“EventTarget”上不存在属性“value”。(2339)


如何定义这样的组件?

我认为您应该使用两种类型的交集,因此它可以是/或。因此,对于
Props
type,使用“&”操作符覆盖两种输入类型,然后在
onChange
事件中,对每个输入类型事件再次使用它(因为它可以是其中之一)。大概是这样的:

import React from 'react';

type Props<T extends boolean = boolean> = { multiline?: T } &
    React.HTMLProps<HTMLTextAreaElement> &
    React.HTMLProps<HTMLInputElement>;

export const Field: React.FC<Props> = ({ multiline, ...props }) => {
    const Element = multiline ? 'textarea' : 'input';

    return <Element {...props} />;
}

// usage

const result = (
    <Field onChange={(e: React.ChangeEvent<HTMLInputElement> & React.ChangeEvent<HTMLTextAreaElement>) => (
        console.log(e.target.value)
    )} />
);
从“React”导入React;
类型Props={multiline?:T}&
React.HTMLProps&
React.HTMLProps;
导出常量字段:React.FC=({multiline,…props})=>{
常量元素=多行?'textarea':'input';
返回;
}
//用法
常数结果=(
(
console.log(例如target.value)
)} />
);

我认为您应该使用两种类型的交叉点,因此它可以是/或。因此,对于
Props
type,使用“&”操作符覆盖两种输入类型,然后在
onChange
事件中,对每个输入类型事件再次使用它(因为它可以是其中之一)。大概是这样的:

import React from 'react';

type Props<T extends boolean = boolean> = { multiline?: T } &
    React.HTMLProps<HTMLTextAreaElement> &
    React.HTMLProps<HTMLInputElement>;

export const Field: React.FC<Props> = ({ multiline, ...props }) => {
    const Element = multiline ? 'textarea' : 'input';

    return <Element {...props} />;
}

// usage

const result = (
    <Field onChange={(e: React.ChangeEvent<HTMLInputElement> & React.ChangeEvent<HTMLTextAreaElement>) => (
        console.log(e.target.value)
    )} />
);
从“React”导入React;
类型Props={multiline?:T}&
React.HTMLProps&
React.HTMLProps;
导出常量字段:React.FC=({multiline,…props})=>{
常量元素=多行?'textarea':'input';
返回;
}
//用法
常数结果=(
(
console.log(例如target.value)
)} />
);
问题:字段中无
T
您已经定义了依赖于
T
的泛型类型
Props
,但您的组件不是泛型的。它总是需要
Props
来解析
HTMLInputElement
Props,因为
布尔扩展true
false
{multiline:boolean}
丢失的原因是您需要在其余的类型周围加上括号

React.HTMLProps 当使用
React.HTMLProps
打字时,我在将不匹配的属性(如
type=“number”
分配给
textarea
rows={5}
分配给
输入时没有出现错误。更严格的类型是
JSX.IntrinsicElements['textarea']
JSX.IntrinsicElements['input']
(解析为类似
React.DetailedHTMLProps
的类型)。如果你想严格执行,那么就使用这些!这也使得
onChange
回调中的
e
值根据元素获得正确的类型

实施 当使用具有限制类型的泛型组件时,我们现在在
return的实现中得到一个错误我认为将它分成两部分(
返回多行?:;
)会有所帮助,但我们仍然会遇到错误。条件句很粗糙。您可以使用
作为
断言来修复问题。当函数的使用保持严格类型化时,我通常可以在函数的实现中进行断言。所以你可以这样做:

type Props<T extends boolean = boolean> = { multiline: T } & (T extends true
    ? JSX.IntrinsicElements['textarea']
    : JSX.IntrinsicElements['input'])

export const Field = <T extends boolean>({ multiline, ...props }: Props<T>) => {
    const Element = multiline ? 'textarea' : 'input';

    return <Element {...props as any} />;
}

用法 无论哪种方式,用法都是非常强类型的!我们的
onChange
回调得到了正确的类型,如
React.ChangeEvent
,如果在
multiline={false}
时传递
textarea
props,我们会得到错误,反之亦然

<Field
    onChange={e => console.log(e.target.value)} // e: React.ChangeEvent<HTMLTextAreaElement>
    multiline={true}
    rows={5} // ok
    type="number" // error
/>
<Field
    onChange={e => console.log(e.target.value)} // e: React.ChangeEvent<HTMLInputElement>
    multiline={false}
    type="number" // ok
    rows={5} // error
/>
console.log(e.target.value)}//e:React.ChangeEvent
多行={true}
行={5}//确定
type=“number”//错误
/>
console.log(e.target.value)}//e:React.ChangeEvent
多行={false}
type=“number”//ok
行={5}//错误
/>
问题:字段中无
T
您已经定义了依赖于
T
的泛型类型
Props
,但您的组件不是泛型的。它总是需要
Props
来解析
HTMLInputElement
Props,因为
布尔扩展true
false
{multiline:boolean}
丢失的原因是您需要在其余的类型周围加上括号

React.HTMLProps 当使用
React.HTMLProps
打字时,我在将不匹配的属性(如
type=“number”
分配给
textarea
rows={5}
分配给
输入时没有出现错误。更严格的类型是
JSX.IntrinsicElements['textarea']
JSX.IntrinsicElements['input']
(解析为类似
React.DetailedHTMLProps
的类型)。如果你想严格执行,那么就使用这些!这也使得
onChange
回调中的
e
值根据元素获得正确的类型

实施 当使用具有限制类型的泛型组件时,我们现在在
return的实现中得到一个错误我认为将它分成两部分(
返回多行?:;
)会有所帮助,但我们仍然会遇到错误。条件句很粗糙。您可以使用
作为
断言来修复问题。当函数的使用保持严格类型化时,我通常可以在函数的实现中进行断言。所以你可以这样做:

type Props<T extends boolean = boolean> = { multiline: T } & (T extends true
    ? JSX.IntrinsicElements['textarea']
    : JSX.IntrinsicElements['input'])

export const Field = <T extends boolean>({ multiline, ...props }: Props<T>) => {
    const Element = multiline ? 'textarea' : 'input';

    return <Element {...props as any} />;
}

用法 无论哪种方式,用法都是非常强类型的!我们的
onChange
回调得到了正确的类型,如
React.changeent
,如果在
多行时传递
textarea
props,我们会得到错误=