繁体   English   中英

在 React 组件上推断通用类型

[英]Inferred Generic Type on React Component

Typescript 对于推断的泛型类型非常好。 例如,如果我编写以下代码:

class AwesomeClass<T> {
    constructor(public val: T) {
        // ...
    }

    public getVal(): T {
        return this.val;
    }
}

const inst = new AwesomeClass("Hello World");
const result = inst.getVal();

result会自动输入到string 漂亮! 我想通过 React 更进一步。

如果我制作以下组件

interface IProps<T> {
    value: T;
    onClick: (result: T) => void;
}
interface IState { }

class AwesomeComponent<T> extends React.Component<IProps<T>, IState> {
    // ...
}

我真的很想推断value必须与onClickresult参数具有相同的类型。 相反,当我初始化组件时

<AwesomeComponent
    value="Hello World"
    onClick={(v) => { console.log(v); }} />;

我收到一个编译错误error TS2322: Type 'string' is not assignable to type 'T'

是否可以在 React 元素的 props 上推断泛型类型?

我意识到 JSX 转换为对React.createElement的调用(它不像我在上面的AwesomeClass示例中那样直接初始化类)并且这可能会使过程复杂化 - 这是一个交易杀手吗? 如果是这样,我可以使用 JSX 语法显式命名泛型类型吗?

这还不可能,这里有个问题: Using lookahead to detect generic JSX elements? .

现在你需要做的是:

interface IProps<T> {
    value: T;
    onClick: (result: T) => void;
}
interface IState { }

class AwesomeComponent<T> extends React.Component<IProps<T>, IState> {
    // ...
}

class ConcreteAwesomeComponent extends AwesomeComponent<string> {}

<ConcreteAwesomeComponent
    value="Hello World"
    onClick={(v) => { console.log(v); }} />;

对于使用功能组件,您可以使用此代码


interface IMessagesProps<T> {
  data: T[];
  titleName: keyof T;
  type: MESSAGE_SYSTEM_TYPE;
}

const Messages = <T extends Record<keyof T, unknown>>(props: IMessagesProps<T>) => {
  const { data, type, titleName } = props;
  return (
    <>
      {data?.length ? (
        data.map((message, index) => {
           return (
            <div key={index}>
              <p >{message[titleName]}</p>
            </div>
          );
        })
      ) : (
        <div>Empty</div>
      )}
    </>
  );
};

export default Messages;

然后你像这样使用 Messages 组件:

interface IMarketNoticeResponse {
  id: string;
  message: string;
}

const messagesDisplayList : IMarketNoticeResponse[] = [
{id:"1",message:"message1"},
{id:"2",message:"message2"}]

<Messages<IMarketNoticeResponse>
      data={messagesDisplayList}
      titleName="message"
      type={messageType}
    />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM