JSX 节点中的 TypeScript 类型参数
TypeScript type arguments in JSX nodes
有什么方法可以为在 JSX 中呈现的组件指定类型参数吗?
例如,考虑这个组件:
interface SelectorProps<T> {
selection: T;
options: T[];
}
class Selector<T> extends React.Component<SelectorProps<T>, {}> {
// ...
}
如果我尝试在 JSX 中呈现此组件:
<Selector selection="a" options={["a", "b", "c"]} />
我收到这些错误:
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'.
我希望 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, {}> {
// ...
}
我已经在我公司创建的组件中使用泛型,但我设法做到的方式并不漂亮。
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>
现在支持 https://github.com/Microsoft/TypeScript/issues/6395 中描述的通用 JSX 元素 - 从 TypeScript 2.9 开始。
您现在应该可以使用:
<Selector<string> selection="a" options={["a", "b", "c"]} />
另请参阅:http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html
有什么方法可以为在 JSX 中呈现的组件指定类型参数吗?
例如,考虑这个组件:
interface SelectorProps<T> {
selection: T;
options: T[];
}
class Selector<T> extends React.Component<SelectorProps<T>, {}> {
// ...
}
如果我尝试在 JSX 中呈现此组件:
<Selector selection="a" options={["a", "b", "c"]} />
我收到这些错误:
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'.
我希望 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, {}> {
// ...
}
我已经在我公司创建的组件中使用泛型,但我设法做到的方式并不漂亮。
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>
现在支持 https://github.com/Microsoft/TypeScript/issues/6395 中描述的通用 JSX 元素 - 从 TypeScript 2.9 开始。
您现在应该可以使用:
<Selector<string> selection="a" options={["a", "b", "c"]} />
另请参阅:http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html