Is there any way to specify type arguments for components rendered in JSX?
For example, consider this component:
interface SelectorProps<T> {
selection: T;
options: T[];
}
class Selector<T> extends React.Component<SelectorProps<T>, {}> {
// ...
}
If I try to render this component in JSX:
<Selector selection="a" options={["a", "b", "c"]} />
I get these errors:
TS2322: Type 'string' is not assignable to type 'T'.
TS2322: Type 'string[]' is not assignable to type 'T[]'. Type 'string' is not assignable to type 'T'.
I would expect T
to be inferred as string
or else some way to specify T=string
in <Selector>
. Is there a solution?
The only workaround I have found is to extend the component to eliminate all type arguments:
class StringSelector extends Selector<string> { }
TypeScript supports embedding, type checking, and compiling JSX directly to JavaScript.
TypeScript is known as an Object-oriented programming language whereas JavaScript is a prototype based language. TypeScript has a feature known as Static typing but JavaScript does not support this feature. TypeScript supports Interfaces but JavaScript does not.
To conclude, JSX = JS, typescript is a superset of Javascript, and there is no comparison between JSX and TypeScript.
What is JSX? JSX stands for JavaScript XML. JSX allows us to write HTML in React. JSX makes it easier to write and add HTML in React.
Generic JSX elements as described in https://github.com/Microsoft/TypeScript/issues/6395 are now supported - since TypeScript 2.9.
You should now be able to use:
<Selector<string> selection="a" options={["a", "b", "c"]} />
See also: http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html
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
or <FooBar foo={{bar: 'works'}} />
should render: <div>{"bar":"works"}</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With