-
我正在尝试将此计算器应用程序转换为TypeScript。
-
这三个函数(handleClick、handleEqual、handleClear(为什么typescript没有对我大喊大叫,要求我指定它们函数的类型?只有一个参数是数字,我为val:number指定了参数的类型。但这真的是我在这里所需要的吗?
-
有没有你推荐的网站可以帮助你找出类型?看起来很困惑。
import React, { useState } from 'react'; import * as math from 'mathjs'; import '../styling/App.css'; import { Button } from './button'; import { Input } from './input' import { ClearButton } from './clear-button'; const App = () => { const [input, setInput] = useState(''); const handleClick = (val: number) => { setInput(input + val) } const handleEqual = () => { setInput(math.evaluate(input)) } const handleClear = () => { setInput(''); } return ( <div className="App"> <div className="calc-wrapper"> <Input input={input}/> <div className="row"> <Button handleClick={handleClick}>7</Button> <Button handleClick={handleClick}>8</Button> <Button handleClick={handleClick}>9</Button> <Button handleClick={handleClick}>/</Button> </div> <div className="row"> <Button handleClick={handleClick}>4</Button> <Button handleClick={handleClick}>5</Button> <Button handleClick={handleClick}>6</Button> <Button handleClick={handleClick}>*</Button> </div> <div className="row"> <Button handleClick={handleClick}>1</Button> <Button handleClick={handleClick}>2</Button> <Button handleClick={handleClick}>3</Button> <Button handleClick={handleClick}>+</Button> </div> <div className="row"> <Button handleClick={handleClick}>.</Button> <Button handleClick={handleClick}>0</Button> <Button handleClick={handleEqual}>=</Button> <Button handleClick={handleClick}>+</Button> </div> <ClearButton handleClear={handleClear} /> </div> </div> ); } export default App;
我现在已经编辑添加了我的按钮组件
import React, {FC} from 'react';
import '../styling/button.css';
// create types for props
type ButtonProps = {
// HandleClick needs to a be a function type with a parameter that takes a ReactNode (since that's the type of props.children in this case, and you want to pass it into that function
handleClick: (children: React.ReactNode) => void; // basically, clicking the reusable component I made, the arg is a ReactNode
// don't need to specify children prop, <ButtonProps> has it by default
}
// set type for value
const isOperator = (val: React.ReactNode) => {
// isNaN() only takes a number parm, and only checks whether a number is set to specal value of 'NaN'
return (typeof val === "number" && !isNaN(val)) || val === "." || val === "=";
}
// generic type, FC
export const Button: FC <ButtonProps> = ({children, handleClick}) => {
return (
<div className={`button-wrapper ${isOperator(children) ? null : "operator"}`}
onClick={() => handleClick(children)}
>
{children}
</div>
)
}
是的,这正是在这个组件中所需要的。Typescpript能够根据使用情况推断出很多。例如,您不需要声明input
状态是string
,因为它基于初始值""
的类型来假设这一点。
这段代码中的typescript类型存在问题,但它们将显示在Button
组件上。CCD_ 5正在接收以CCD_ 7作为其自变量的CCD_。可以吗?如何处理单击*
按钮的操作?你是如何调用一个只能接受number
的函数的?
如果我们的按钮确实接受了我们提供的道具,那么它会看起来像这样:
interface ButtonProps {
handleClick: (val: number) => void;
children: ReactNode; // this is the default so it's not actually needed here
}
const Button: React.FC<ButtonProps> = ({ handleClick, children }) => (
<button onClick={() => handleClick(children)}>{children}</button>
);
调用handleClick(children)
:时会出现错误
类型为"ReactNode"的参数不可分配给类型为"number"的参数。
类型"undefined"不可分配给类型"number">
好的,所以我们不能只允许任何children
。如果我们将{children: number;}
添加到ButtonProps
,则这修复了Button
中的错误,但在App
:中创建了新错误
"按钮"组件不接受文本作为子元素。
所以我们需要将children
道具读取为string
。我们的Button
将是这样的:
interface ButtonProps {
handleClick: (val: string) => void;
children: string;
}
const Button: React.FC<ButtonProps> = ({ handleClick, children }) => (
<button onClick={() => handleClick(children)}>{children}</button>
);
现在我们在应用程序中得到一个不同的错误:
Type'(val:number(=>void"不可分配给类型"(val:string(=>无效的
这给我们带来了一个完整的循环。我们只需更改handleClick
函数的类型,就完成了!
const handleClick = (val: string) => {
setInput(input + val);
};
代码沙盒链接