Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.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
Reactjs Typescript接口-使用缩小的union类型参数实现函数_Reactjs_Typescript - Fatal编程技术网

Reactjs Typescript接口-使用缩小的union类型参数实现函数

Reactjs Typescript接口-使用缩小的union类型参数实现函数,reactjs,typescript,Reactjs,Typescript,我正在尝试构建一个通用的React组件,它允许数字、字符串或日期值。我希望组件的用户能够在值更新时定义回调,并允许回调将值定义为数字、字符串或日期 下面是一个淡化的例子,说明了我试图做的全部工作(我知道这个具体的例子可以通过强制值始终是字符串来解决,但这不是这个问题的目的): 从“React”导入React; //联合型 类型ValueType=编号|字符串|日期; //通用组件 接口输入道具{ 值:ValueType; onChange:(值:ValueType)=>void;//( onCh

我正在尝试构建一个通用的React组件,它允许数字、字符串或日期值。我希望组件的用户能够在值更新时定义回调,并允许回调将值定义为数字、字符串或日期

下面是一个淡化的例子,说明了我试图做的全部工作(我知道这个具体的例子可以通过强制
始终是
字符串
来解决,但这不是这个问题的目的):

从“React”导入React;
//联合型
类型ValueType=编号|字符串|日期;
//通用组件
接口输入道具{
值:ValueType;
onChange:(值:ValueType)=>void;//(
onChange(e.target.value)}/>
);
//通用组件的实现
接口测试道具{
onInputUpdate:(值:字符串)=>void;
}
常量测试=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//
);
导出默认测试;
我理解为什么这不起作用,但我不知道如何让它以我想要的方式工作

我还尝试使用泛型,即
onChange:(value:T)=>void
,结果类似

我知道有两种方法可以“修复”它,但如果可能的话,我想避免它们:

  • 将签名
    onChange:(值:any)=>void
  • 强制用户在实现回调时使用
    ValueType
    类型
提前感谢您的帮助


Edit
onChange:(value:any)=>void
可以将函数实现为
onChange:(value:string)=>{}
,有没有办法做到这一点,但将其限制为属于
ValueType
的类型,而不是
any

定义如下接口:

interface InputProps<T extends ValueType> {
    value:T,
    onChange: ((value: T) => void);
}
接口输入属性{
值:T,
onChange:((值:T)=>无效);
}

尽管我可能误解了您的意思-如果在运行时这些类型中的任何一种类型的值都可能不同,那么您将不得不在处理程序中进行类型测试。

如下定义接口:

interface InputProps<T extends ValueType> {
    value:T,
    onChange: ((value: T) => void);
}
接口输入属性{
值:T,
onChange:((值:T)=>无效);
}

尽管我可能误解了您的意思-如果在运行时这些类型中的任何一种类型的值都会发生变化,那么您将不得不在处理程序中进行类型测试。

我认为您正在寻找这样的smth:

从“React”导入React;
//联合型
类型ValueType=编号|字符串|日期;
//通用组件
接口输入道具{
值:T;
onChange:(值:U)=>void;//(
onChange(e.target.value)}/>
);
//通用组件的实现
接口测试道具{
onInputUpdate:(值:U)=>无效;
}
常量测试=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是数字
/>
);
常量Test2=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是字符串
/>
);
常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
/>
);
导出默认测试;

有一个缺点:如果为
onInputUpdate
提供泛型参数,可能会破坏类型。 例如:


常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//e是字符串,而不是预期的日期
/>
);
第二种方法

从“React”导入React;
//联合型
类型ValueType=编号|字符串|日期;
//通用组件
接口输入道具{
值:T;
onChange:(值:U)=>void;//
}
常量输入=({value,onChange}:InputProps)=>(
onChange(e.target.value)}/>
);
//通用组件的实现
接口测试道具{
onInputUpdate:(值:U)=>无效;
}
常量测试=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是文本2
/>
);
常量Test2=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是文本“2”
/>
);
常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
/>
);
常量Test4=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
/>
);
导出默认测试;

我想您正在寻找这样的smth:

从“React”导入React;
//联合型
类型ValueType=编号|字符串|日期;
//通用组件
接口输入道具{
值:T;
onChange:(值:U)=>void;//(
onChange(e.target.value)}/>
);
//通用组件的实现
接口测试道具{
onInputUpdate:(值:U)=>无效;
}
常量测试=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是数字
/>
);
常量Test2=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是字符串
/>
);
常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
/>
);
导出默认测试;

有一个缺点:如果为
onInputUpdate
提供泛型参数,可能会破坏类型。 例如:


常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//e是字符串,而不是预期的日期
/>
);
第二种方法

从“React”导入React;
//联合型
类型ValueType=编号|字符串|日期;
//通用组件
接口输入道具{
值:T;
onChange:(值:U)=>void;//
}
常量输入=({value,onChange}:InputProps)=>(
onChange(e.target.value)}/>
);
//通用组件的实现
接口测试道具{
onInputUpdate:(值:U)=>无效;
}
常量测试=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是文本2
/>
);
常量Test2=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是文本“2”
/>
);
常量Test3=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
/>
);
常量Test4=({onInputUpdate}:TestProps)=>(
onInputUpdate(e)}//好的,e是日期
interface InputProps {
  value: ValueType;
  onChange(value: ValueType): void;  // onChange declared as a method (does what I expect)

  // onChange: (value: ValueType) => void;  // onChange declared as a property (strict)
}
type InputProps = {
    value: string;
    onChange: (value: string) => void;
} | {
    value: number;
    onChange: (value: number) => void;
} | {
    value: Date;
    onChange: (value: Date) => void;
}
type InputProps = ValueType extends infer T ?
    T extends unknown ? { value: T, onChange: (value: T) => void } : never : never;
const Test = ({ onInputUpdate }: TestProps) => (
    <Input
        value="test"
        onChange={(e: string) => onInputUpdate(e)}
    />
);
const Input = ({ value, onChange }: InputProps) => (
    <input
        value={value.toString()}
        onChange={(e) => (onChange as (value: ValueType) => void)(e.target.value)}
    />
);