typescript 在JSX内部使用的“Array.reduce()”中出现类型脚本错误,JSX作为返回值

yzuktlbb  于 2023-02-05  发布在  TypeScript
关注(0)|答案(1)|浏览(162)

我有这样一段代码(为了简洁而简化):

function getText(item: {id: number, value: string}[]) {
    return (
        <span>
            {item.map(({ value }) => <>{value}</>)
                .reduce((p, c, i) => [p, <span key={i} className="syntax-operator">, </span>, c])
            }
        </span>
    );
}

TypeScript抱怨reduce()函数的返回值,说:

Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, keyts(2739)
lib.es5.d.ts(1459, 24): The expected type comes from the return type of this signature.

我完全不知道如何修复它。我试着修改类型等,但没有任何效果。一开始我只是忽略了带有注解的行,因为代码在其他方面工作正常。但这是一个库的代码,当我构建它并试图在项目中使用它时,输出是混乱的,所以函数一定是在编译过程中由于不是“正确的”TypeScript而中断的。
输出的外观(编译前的外观)与使用包时的外观(编译后的外观):

有人知道如何“正确地”摆脱错误吗?

rur96b6h

rur96b6h1#

您不需要为每个文本值提供一个片段:stringReactNode,因此可以将它们作为裸子对象包含在<span>中。
下面发生的事情是,第一项的value被追加到一个数组中,然后每个后续项的value被追加到span元素中的逗号后面,形成了一个逗号居中的列表。
参考:Array.prototype[@@iterator]()
TSPlayground代码

body { font-family: sans-serif; }
.syntax-operator { background-color: red; color: white; }
<div id="root"></div><script src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.development.js"></script><script src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.development.js"></script><script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.20.15/babel.min.js"></script><script>Babel.registerPreset("tsx", {presets: [[Babel.availablePresets["typescript"], {allExtensions: true, isTSX: true}]]});</script>
<script type="text/babel" data-type="module" data-presets="tsx,react">

import {type ReactElement, type ReactNode} from "react";

// This Stack Overflow snippet demo uses UMD modules
const {StrictMode} = React;

type Item = {
  id: number;
  value: string;
};

function ItemsAsText ({items}: { items: readonly Item[] }): ReactElement {
  const iter = items[Symbol.iterator]();
  const firstResult = iter.next();
  if (firstResult.done) return (<span></span>);

  const results: ReactNode[] = [firstResult.value.value];

  for (const {id, value} of iter) {
    results.push((<span key={id} className="syntax-operator">, </span>), value);
  }

  return (<span>{results}</span>);
}

const items: Item[] = [
  {id: 1, value: "foo"},
  {id: 2, value: "bar"},
  {id: 3, value: "baz"},
];

const reactRoot = ReactDOM.createRoot(document.getElementById("root")!);

reactRoot.render(
  <StrictMode>
    <ItemsAsText items={items} />
  </StrictMode>
);

</script>

相关问题