BennKingy
BennKingy

Reputation: 1593

Typescript spfx error: Property 'news' does not exist on type 'Readonly<{}>

I am trying to create an spfx react component that will display a rss feed to the browser. I have this working in a play ground, but spfx uses typescript and not sure how to combat the type error below.

RssFeed.ts

import * as React from 'react';
import styles from './RssFeed.module.scss';
import { IRssFeedProps } from './IRssFeedProps';
import { escape } from '@microsoft/sp-lodash-subset';
import * as $ from "jquery";
import { string } from 'prop-types';

export default class RssFeed extends React.Component<IRssFeedProps,        
{}> {

constructor(props) {
    super(props);
    this.state = { news: [] };
}

componentDidMount() {
    this.getNews();
}

getNews() {
    $.get(
  "https://www.feed.co.uk/news/feed",
  function(data) {
    var $xml = $(data);
    var items = [];

    $xml.find("item").each(function() {
      var $this = $(this);
      items.push({
        title: $this.find("title").text(),
        link: $this.find("link").text()
        // link: $this.find("link").text(),
      });
    });

    this.setState({ news: items }, function() {
      // callback function to check what items going onto the array
      console.log(this.state.news);
    });
  }.bind(this),
  "xml"
);
}

 public render(): React.ReactElement<IRssFeedProps> {
  return (
  <div className={ styles.rssFeed }>
        {this.state.news.map(item => (
        <div className="panel" key={item.title}>
          <h2 className="panel-title">
            {item.title}
          </h2>
          <span>{item.link}</span>
        </div>
      ))}
  </div>
);
}
}

IRssFeedProps.ts

export interface IRssFeedProps {
description: string;
}

This is the error: Error - [tsc] src/webparts/rssFeed/components/RssFeed.tsx(47,25): error TS2339: Property 'news' does not exist on type 'Readonly<{}>'.

Upvotes: 1

Views: 2071

Answers (1)

Mikhail Korotkov
Mikhail Korotkov

Reputation: 32

You are passing an empty interface for your component state.

interface ComponentProps{
  firstProp: string;
}

interface ComponentState {
  firstPropsOnState: string;
}

then you could use it like that

class MyComponent extends React.Component<ComponentProps, ComponentState> {...}

Since you are passing an empty interface TypeScript will complain that news property on state does not exist because you declared an empty state. Just add that property to your interface and pass it down when you create your component and it will work.

https://www.typescriptlang.org/docs/handbook/react-&-webpack.html#write-some-code

In the docs they don't have an expample of defined interface for the state which might be misleading for newcomers to TypeScript. The second generic type which you pass there is your actual state.

Hope it made things clear for you.

Upvotes: 2

Related Questions