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,我们会得到错误=