我想实现以下内容(在React/TypeScript (.tsx)中)
Main.tsx(编辑:botCommands
是一个数组,其中可以有多个对象(与command
和botResponse()
)
function Main() {
return (
<TestComponent
botVariables={{
tasks: [],
groups: []
}}
botCommands={[
{
command: "-help",
botResponse(botVariables) {
return botVariables.tasks[0]
}
}
]}
/>
);
}
TestComponent.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
我想在功能botResponse()
类型(目前any
)是自动调整。从而自动将botVariables
的内容作为类型。
简单地说,如果我在Main.tsx
中写入botResponse()
函数"botVariables."tasks
和groups
可以由IDE推荐给我。botVariables
中的数据可以更改,因此您不能仅在TestComponent.tsx
文件中创建接口。
我尝试使用typescript泛型,但不幸失败了。谢谢你的帮助!
如果我正确理解您的要求,botVariables
可以是任何东西,但是我们提供给TestComponent
的botVariables
和botCommands
需要相互匹配。也就是说,botCommands
中botResponse
函数的参数与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
prop中推断出来。如果botCommands
不匹配,typescript会报错。
在这个例子中:
function Main() {
return (
<TestComponent
botVariables={{
tasks: ["first"],
groups: ["something"]
}}
botCommands={[{
command: "-help",
botResponse(botVariables) {
return botVariables.tasks[0]
}
}]}
/>
);
}
botResponse
函数的推断签名是完整和正确的:
(method) BotCommand<{ tasks: string[]; groups: string[]; }>.botResponse(botVariables: {
tasks: string[];
groups: string[];
}): string
为了得到正确的推断,我不得不使用["first"]
而不是空数组,因为空数组类型为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;
}
在这两种情况下你都需要"识别"在使用对象之前,对象的当前类型。要做到这一点,你可以使用Typeguard。
function isMyObject(x: unknown): x is MyObject {
return (x as MyObject).tasks !== undefined
}
更多信息请看这个游乐场