我试图对我的React-Typescript项目进行一些简化,但是我陷入了如何正确注释类型的困境。这是我正在使用的代码的精简示例:
https://codesandbox.io/s/working-example-qc5cq
// WORKING EXAMPLE
import * as React from "react";
import { render } from "react-dom";
const App: React.FC = () => {
const handleClick = (value: string | number): void => {
if (typeof value === "string") {
// Do some string logic...
console.log(`String: ${value}`);
} else if (typeof value === "number") {
// Do some number logic
console.log(`Number: ${value}`);
}
};
return (
<div>
<Button handleClick={handleClick} value="Hello" />
<Button handleClick={handleClick} value={42} />
</div>
);
};
interface Props {
handleClick: (value: string | number) => void;
value: string | number;
}
const Button: React.FC<Props> = ({ handleClick, value }) => (
<button onClick={(): void => handleClick(value)}>{value}</button>
);
const rootElement = document.getElementById("root");
render(<App />, rootElement);
我想要做的是将handleClick
-函数拆分为两个单独的函数;一个用于处理string
,一个用于处理number
。当我尝试为Props
组件键入Button
时出现问题。这是我目前的位置:
https://codesandbox.io/s/wip-example-fied2
// WIP
import * as React from "react";
import { render } from "react-dom";
const App: React.FC = () => {
const handleStringClick = (string: string) => {
// Do some string logic...
console.log(`String: ${string}`);
};
const handleNumberClick = (number: number): void => {
// Do some number logic
console.log(`Number: ${number}`);
};
return (
<div>
<Button handleClick={handleStringClick} value="Hello" />
<Button handleClick={handleNumberClick} value={42} />
</div>
);
};
interface StringProps {
handleClick: (string: string) => void;
value: string;
}
interface NumberProps {
handleClick: (number: number) => void;
value: number;
}
type Props = StringProps | NumberProps;
const Button: React.FC<Props> = ({ handleClick, value }) => (
<button onClick={(): void => ?handleClick(value)}>{value}</button>
);
const rootElement = document.getElementById("root");
render(<App />, rootElement);
我收到的错误是在handleClick(value)
上:
类型'ReactText'的参数不能分配给类型的参数 '决不'。不能将“字符串”类型分配给“从不”类型。ts(2345)
这是可以理解的,因为value
的类型被解释为string | number
(实际上是ReactText
,但这是React的简写),没有handleClick
的版本可以处理这种情况。
问题是,我可以以某种方式注释Props
以便handleClick
取决于value
的类型吗?换句话说,如果我将value
设置为number
,我可以使Typescript理解并强迫我传递handleClick(number)
函数吗?如果我的思维定势或要达到的目标有点缺陷,请随时向我指出更好的方向。
答案 0 :(得分:0)
一种实现此目的的方法是使Button
通用:
type Props<T extends string | number> = {
handleClick: (argument: T) => void;
value: T;
}
const Button= <T extends string | number,>({ handleClick, value }: Props<T>) => (
<button onClick={(): void => handleClick(value)}>{value}</button>
);
<Button handleClick={arg => { /** `arg` is of type `42` */}} value={42} />
答案 1 :(得分:0)
感谢答案Karol!我能够根据您的建议调整代码;我照原样离开了Props
,然后扩展了Button
代码,使其具有返回类型:
const Button = <T extends string | number>({
handleClick,
value
}: Props<T>): JSX.Element => (
<button onClick={(): void => handleClick(value)}>{value}</button>
);
还找到了一个很好的消息来源:Passing Generics to JSX Elements in TypeScript