JSX节点中的TypeScript类型参数
有什么方法可以为在JSX中呈现的组件指定类型参数吗?JSX节点中的TypeScript类型参数
例如,考虑这个组件:
interface SelectorProps<T> {
selection: T;
options: T[];
}
class Selector<T> extends React.Component<SelectorProps<T>, {}> {
// ...
}
如果我尝试呈现在JSX这个组件:
<Selector selection="a" options={["a", "b", "c"]} />
我得到这些错误:
TS2322:类型“字符串“不能分配给'T'类型。
TS2322:类型'string []'不可分配给类型'T []'。类型'字符串'不是 可分配给类型'T'。
我希望T
被推断为string
或者某种方式<Selector>
指定T=string
。有解决方案吗?
我发现的唯一的解决方法是扩展组件,以消除所有类型的参数:
class StringSelector extends Selector<string> { }
试试这个。你的接口应该明确声明它所期望的值的类型。这是使用打字稿的关键。如果你真的知道会发生什么,你不应该推断任何事情。
interface SelectorProps {
selection: string | number; // This means selection can take in either a string or a number
options: string[] | number[];
}
class Selector extends React.Component<SelectorProps, {}> {
// ...
}
我已经gotton仿制药我在公司创建的一个组成部分的工作,但他们的方式我设法做到这一点并不漂亮。
GenericComponent.tsx:
import * as React from "react";
interface IGenericComponentProps<T, S> {
propT: T;
propS: S;
}
interface IGenericComponentState<T, S> {}
export class GenericComponent<T, S> extends React.Component<
IGenericComponentProps<T, S>,
IGenericComponentState<T, S>
> {
public render(): JSX.Element {
return (
<div>Generic component!</div>
);
}
}
export default GenericComponent;
GenericComponentImplementation.tsx:
import * as React from "react";
// This is the ugly part
import GenericComponentBase from "./GenericComponent";
// This is where you get to define the generic type arguments
interface StringAndNumberComponentBase { new(): GenericComponentBase<string, number>; };
const StringAndNumberComponent = GenericComponentBase as StringAndNumberComponentBase ;
export default(): JSX.Element => {
return (
<StringAndNumberComponent
propT="test"
propS={2}
/>
);
};
我觉得我得到了这个问题的GitHub在当时这样的信息: https://github.com/Microsoft/TypeScript/issues/3960
interface FooProps<T> { foo: T; }
class Foo<T> extends React.Component<FooProps<T>, any> {
render() {
return <div>{ JSON.stringify(this.props.foo) }</div>;
}
}
type FooBar = new() => Foo<{bar: string}>;
const FooBar = Foo as FooBar;
class FooBarContainer extends React.Component<any, any> {
render() {
return <FooBar foo={{bar: 'works'}} />;
}
}
FooBarContainer
或<FooBar foo={{bar: 'works'}} />
应呈现:<div>{"bar":"works"}</div>
的完整的上下文有点难受,遵循“foobar的” jarble,但是这真的是比使用'extends'我的解决方法有什么不同? – Aaron
尚未。见https://github.com/Microsoft/TypeScript/issues/6395 –
谢谢,似乎涵盖了这个问题。现在坚持我的'扩展'解决方法。 – Aaron