Почему эти дочерние элементы как массив не отображаются в TS?

У меня мертвый простой компонент. Прекрасно работает в JavaScript.

const Test = (props: any) => <div>{props.children}</div>;

const Root: React.SFC<{}> = props => {
  return (
    <div className="Root">
      <h1>hello world.</h1>
      <Test>{[...Array(20)].map((_, index) => <h1>test{index}</h1>)}</Test>
    </div>
  );
};

export default Root;

Но не работает в машинописи. Зачем?

Оба используют одну и ту же версию React.

РЕДАКТИРОВАТЬ:

TypeScript: https://codepen.io/anon/pen/eKGoWo

JavaScript: https://codepen.io/anon/pen/GGMLOv

1 ответ

Решение

Это работает, если вы измените его с этой карты массива распространения на

<Test>{Array.from({length:20}, (_, index) => <h1 key={index}>test{index}</h1>)}</Test>

(Я также добавил key к этому, так как React жалуется, как только он начинает работать.:-))

Не работает: https://codepen.io/anon/pen/XYeQzv?editors=1010

Работает: https://codepen.io/anon/pen/eKGoya?editors=1010

Это связано с тем, как TypeScript передает эту распространенную нотацию. TypeScript преобразует это [...Array(20)].map(/*...*/) к этому:

Array(5).slice().map(/*...*/)

Проблема в том, что Array(20) создает массив длиной 20 без записей в нем. slice повторяет это. map посещает только те записи, которые действительно существуют в массиве, а не пробелы. Но [...Array(20)] создает массив с 20 записями, содержащий undefined, который map посетит:

const a1 = [...Array(5)];
console.log(0 in a1);   // true
const a1m = a1.map((_, index) => index);
console.log(0 in a1m);  // true
console.log(a1m);       // 0, 1, 2, 3, 4

const a2 = Array(5).slice();
console.log(0 in a2);   // false
const a2m = a2.map((_, index) => index);
console.log(0 in a2m);  // false
console.log(a2m);       // (gaps)
Look in the real console (the snippet console gives the impression values exist in the array when they don't).

Yury Tarabanko любезно нашел сообщение об ошибке для него.

Другие вопросы по тегам