我有以下用TypeScript编写的联合类型:
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 { /* ... */ }
}
}
现在我收到有关onChange
电话的错误:
TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((value: string) => void) | ((editorState: EditorState) => void)' has no compatible call signatures.
我该怎么办?我在StackOverflow上看到了关于这个主题的一些其他问题,但是它们都没有说明我的情况。谢谢!
答案 0 :(得分:2)
问题是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
可以&# 39; t处理字符串作为参数(至少根据声明)。你可以做以下两件事之一:
更改MultiLineTextFieldPropTypes
上的定义以允许字符串参数:
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
}