Typescript 无法调用其类型在联合类型中缺少调用签名的表达式
我使用TypeScript编写了以下联合类型:Typescript 无法调用其类型在联合类型中缺少调用签名的表达式,typescript,union-types,Typescript,Union Types,我使用TypeScript编写了以下联合类型: interface SingleLineTextFieldPropTypes { multiLine: false; value: string; disabled?: boolean; placeholder?: string; readOnly?: boolean; type?: string; className?: string; onChange: (value: string) => void;
interface SingleLineTextFieldPropTypes {
multiLine: false;
value: string;
disabled?: boolean;
placeholder?: string;
readOnly?: boolean;
type?: string;
className?: string;
onChange: (value: string) => void;
}
interface MultiLineTextFieldPropTypes {
multiLine: true;
readOnly?: boolean;
disabled?: boolean;
placeholder?: string;
editorState: EditorState;
onChange: (editorState: EditorState) => void;
}
type PropTypes =
SingleLineTextFieldPropTypes |
MultiLineTextFieldPropTypes;
(这些接口的唯一相关成员是onChange
函数)
我在React组件中使用它们,如下所示:
class Component extends React.Component<PropTypes> {
render() {
if (this.props.multiLine === false) {
return (
<input
type={this.props.type}
readOnly={this.props.readOnly}
disabled={this.props.disabled}
placeholder={this.props.placeholder}
value={this.props.value}
onChange={(e: React.FormEvent<HTMLInputElement>) => {
this.props.onChange((e.target as HTMLInputElement).value as string);
// ^^^^^^^^^^^^^^^^^^^ here is the error
}}
className={classnames('ui-textfield', this.props.className)}
/>
);
}
else { /* ... */ }
}
}
我该怎么办?关于这个话题,我在StackOverflow上看到了一些其他问题,但没有一个能说明我的情况。谢谢大家! 问题在于
onChange
在两个接口中具有不同的类型,因此生成的类型将是:
onChange: ((value: string) => void) | ((editorState: EditorState) => void)
Typescript不会合并调用签名,因此结果将不可调用。如果两个接口具有相同的签名,则生成的onChange
将可调用:
interface EditorState { }
interface SingleLineTextFieldPropTypes {
onChange: (value: EditorState) => void;
}
interface MultiLineTextFieldPropTypes {
onChange: (editorState: EditorState) => void;
}
type PropTypes = SingleLineTextFieldPropTypes | MultiLineTextFieldPropTypes;
let d: PropTypes;
d.onChange({})
编辑:
问题在于逻辑中有一个字段是SingleLineTextFieldPropTypes
或MultiLineTextFieldPropTypes
,您试图将onChange
传递给string
,但MultiLineTextFieldPropTypes
无法将字符串作为参数处理(至少根据声明)。您可以做以下两件事之一:
MultilinextFieldPropTypes
上的定义以允许使用字符串参数:
interface MultiLineTextFieldPropTypes {
// onChange has two possible signatures,
// note you can't use string|EditorState as that would not get merged.
onChange: {
(editorState: string) : void
(editorState: EditorState) : void
};
}
type PropTypes = SingleLineTextFieldPropTypes | MultiLineTextFieldPropTypes;
let editor: PropTypes;
editor.onChange("")
if(editor.multiLine === true) {
let state : EditorState = null; // Get the state
editor.onChange(state) // TS knows editor is MultiLineTextFieldPropTypes because of the check and the way multiLine is declared.
}else {
let value = "" // Get the simple value
editor.onChange("") // editor is SingleLineTextFieldPropTypes
}
问题是,
onChange
在两个接口中具有不同的类型,因此生成的类型将是:
onChange: ((value: string) => void) | ((editorState: EditorState) => void)
Typescript不会合并调用签名,因此结果将不可调用。如果两个接口具有相同的签名,则生成的onChange
将可调用:
interface EditorState { }
interface SingleLineTextFieldPropTypes {
onChange: (value: EditorState) => void;
}
interface MultiLineTextFieldPropTypes {
onChange: (editorState: EditorState) => void;
}
type PropTypes = SingleLineTextFieldPropTypes | MultiLineTextFieldPropTypes;
let d: PropTypes;
d.onChange({})
编辑:
问题在于逻辑中有一个字段是SingleLineTextFieldPropTypes
或MultiLineTextFieldPropTypes
,您试图将onChange
传递给string
,但MultiLineTextFieldPropTypes
无法将字符串作为参数处理(至少根据声明)。您可以做以下两件事之一:
MultilinextFieldPropTypes
上的定义以允许使用字符串参数:
interface MultiLineTextFieldPropTypes {
// onChange has two possible signatures,
// note you can't use string|EditorState as that would not get merged.
onChange: {
(editorState: string) : void
(editorState: EditorState) : void
};
}
type PropTypes = SingleLineTextFieldPropTypes | MultiLineTextFieldPropTypes;
let editor: PropTypes;
editor.onChange("")
if(editor.multiLine === true) {
let state : EditorState = null; // Get the state
editor.onChange(state) // TS knows editor is MultiLineTextFieldPropTypes because of the check and the way multiLine is declared.
}else {
let value = "" // Get the simple value
editor.onChange("") // editor is SingleLineTextFieldPropTypes
}
同样的问题@我不这么认为。在我的例子中,我希望
PropTypes
被解析为一个有区别的联合,因为我有multiLine
应该这样做。同样的问题@我不这么认为。在我的例子中,我希望PropTypes
被解析为一个有区别的联合,因为我有multiLine
可以做到这一点。嗨!谢谢你的回答!我已经知道了,但是我想您已经看到了在这些接口中使用与我的代码不同的签名的必要性。你推荐什么?@Victor添加了两种可能的解决方案,而我决定将我的反应成分分成两种。然而,你的解决方案似乎有效,所以我接受这个答案!非常感谢。你好谢谢你的回答!我已经知道了,但是我想您已经看到了在这些接口中使用与我的代码不同的签名的必要性。你推荐什么?@Victor添加了两种可能的解决方案,而我决定将我的反应成分分成两种。然而,你的解决方案似乎有效,所以我接受这个答案!非常感谢。