![](/img/trans.png)
[英]Typescript/React functional component's props function - what type?
[英]React: TypeScript generics, auto switch parameter-type from function (function as props)
我想实现以下(在 React/TypeScript (.tsx) 中)
Main.tsx (编辑: botCommands
是一个数组,其中可以包含多个对象(使用command
和botResponse()
)
function Main() {
return (
<TestComponent
botVariables={{
tasks: [],
groups: []
}}
botCommands={[
{
command: "-help",
botResponse(botVariables) {
return botVariables.tasks[0]
}
}
]}
/>
);
}
测试组件.tsx
interface BotCommand {
command: string;
botResponse(botVariables: any): string;
}
interface TestComponentProps {
botVariables: any;
botCommands: BotCommand[];
}
export default function TestComponent(props: TestComponentProps) {
return (
// magic
);
}
在Main.tsx
我希望在 function botResponse()
中自动调整类型(当前为any
)。 这样会自动将botVariables
的内容作为类型。
简单地说,如果我在Main.tsx
botResponse()
function “botVariables”中写入 Main.tsx。 IDE 可以向我建议tasks
和groups
。 botVariables
中的数据可以更改,因此您不能只在TestComponent.tsx
文件中创建接口。
我尝试使用 typescript generics 但不幸失败了。 感谢帮助!
如果我正确理解您的要求, botVariables
可以是任何东西,但我们提供给TestComponent
的botVariables
和botCommands
需要相互匹配。 即botCommands中botResponse
function的botCommands
与botVariables
prop的类型相同。
为此,我们将BotCommand
接口设为通用接口,其中类型T
表示botResponse
变量的类型。
interface BotCommand<T> {
command: string;
botResponse(botVariables: T): string;
}
我们的TestComponentProps
也是通用的,我们将相同的T
应用于botVariables
和botCommands
。
interface TestComponentProps<T> {
botVariables: T;
botCommands: BotCommand<T>[];
}
这意味着该组件也是通用的。
export default function TestComponent<T>(props: TestComponentProps<T>) {...}
从传递的变量创建响应没有问题,因为两个props
共享相同的T
。
export default function TestComponent<T>({ botVariables, botCommands }: TestComponentProps<T>) {
return (
<div>
<h1>Bot Output</h1>
{botCommands.map(command => (
<div>
<div>Bot recieved command {command.command}</div>
<div>Bot responded {command.botResponse(botVariables)}</div>
</div>
))}
</div>
);
}
使用TestComponent
时不需要显式声明泛型T
,因为它可以从botVariables
中推断出来。 如果botCommands
不匹配,typescript 会抱怨。
在这个例子中:
function Main() {
return (
<TestComponent
botVariables={{
tasks: ["first"],
groups: ["something"]
}}
botCommands={[{
command: "-help",
botResponse(botVariables) {
return botVariables.tasks[0]
}
}]}
/>
);
}
botResponse
function 的推断签名是完整且正确的:
(method) BotCommand<{ tasks: string[]; groups: string[]; }>.botResponse(botVariables: {
tasks: string[];
groups: string[];
}): string
为了得到正确的推断,我不得不使用["first"]
而不是空数组,因为空的 arrays 被输入为never[]
但我们想要string[]
。 您可以使用空数组,但必须显式设置它的类型。
欢迎来到 StackOverflow 社区。
Typescript 无法自动检测您的参数类型。
如果变量是一组有限的类型,您可以使用联合类型。
interface MyObject {
tasks: string[]
}
interface BotCommand {
command: string;
botResponse: (botVariables: string | number | MyObject) => string;
}
泛型类型示例
interface BotCommand {
command: string;
botResponse: <T extends unknown>(botVariables: T) => string;
}
在这两种情况下,您都需要在使用 object 之前“识别”它的当前类型。 为此,您可以使用Typeguard 。
function isMyObject(x: unknown): x is MyObject {
return (x as MyObject).tasks !== undefined
}
有关更多信息,请查看这个游乐场。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.