I have the following error, and below I will try to explain what I am trying to accomplish:
[ts]
Argument of type '{ status: string; DetailsAnnouncementListItemState: { items: IListItem[]; columns: undefined[]; }...' is not assignable to parameter of type 'Pick<IFactoryMethodState, "status" | "DetailsAnnouncementListItemState">'.
Types of property 'DetailsAnnouncementListItemState' are incompatible.
Type '{ items: IListItem[]; columns: undefined[]; }' is not assignable to type 'IDetailsAnnouncementListItemState'.
Types of property 'items' are incompatible.
Type 'IListItem[]' is not assignable to type 'IAnnouncementListItem[]'.
Type 'IListItem' is not assignable to type 'IAnnouncementListItem'.
Property 'announcementBody' is missing in type 'IListItem'.
I have a base interface and extended interfaces that represent list items in sharepoint depending on the list, a normal list has id, title, createdby, createddate, etc, other lists inherit the same fields, but add additional fields, so my design is like this:
export interface IListItem {
[key: string]: any;
id: string;
title: string;
modified: Date;
created: Date;
modifiedby: string;
createdby: string;
}
import {IListItem} from './IListItem';
export interface INewsListItem extends IListItem {
newsheader: string;
newsbody: string;
expiryDate: Date;
}
import {IListItem} from './IListItem';
export interface IDirectoryListItem extends IListItem {
firstName: string;
lastName: string;
mobileNumber: string;
internalNumber: string;
}
import {IListItem} from './IListItem';
export interface IAnnouncementListItem extends IListItem {
announcementBody: string;
expiryDate: Date;
}
Now, I have a factory method design pattern like this:
import { IListItem } from './models/IListItem';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
export interface IFactory{
getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[];
}
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { IListItem} from './models/IListItem';
import { IFactory } from './IFactory';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';
export class ListItemFactory implements IFactory{
getItems(requester: SPHttpClient, siteUrl: string, listName: string): IListItem[] {
switch(listName) {
case 'List':
let items: IListItem[];
requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
return response.json();
})
.then((response: { value: IListItem[] }): void => {
items= response.value;
});
return items;
case 'News':
let newsitems: INewsListItem[];
requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse): Promise<{ value: INewsListItem[] }> => {
return response.json();
})
.then((response: { value: INewsListItem[] }): void => {
newsitems= response.value;
});
return newsitems;
case 'Announcements':
let announcementitems: IAnnouncementListItem[];
requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse): Promise<{ value: IAnnouncementListItem[] }> => {
return response.json();
})
.then((response: { value: IAnnouncementListItem[] }): void => {
announcementitems= response.value;
});
return announcementitems;
case 'Directory':
let directoryitems: IDirectoryListItem[];
requester.get(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items?$select=Title,Id`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse): Promise<{ value: IDirectoryListItem[] }> => {
return response.json();
})
.then((response: { value: IDirectoryListItem[] }): void => {
items= response.value;
});
return directoryitems;
default:
return null;
}
}
}
so far so god, however on my react component when I try to use it:
private readItems(): void {
this.setState({
status: 'Loading all items...'
});
let factory = new ListItemFactory();
//Here its where we actually use the pattern to make our coding easier.
switch(this.props.listName)
{
case "List":
let listItems = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
this.setState({
status: `Successfully loaded ${listItems.length} items`,
DetailsListItemState : {
items: listItems,
columns: [
]
}
});
break;
case "Announcements":
let announcementlistItems = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
this.setState({
status: `Successfully loaded ${listItems.length} items`,
DetailsAnnouncementListItemState : {
items: announcementlistItems,
columns: []
}
});
break;
case "News":
let newsFactory = new NewsListItemFactory();
let newsListItems = newsFactory._getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
this.setState({
status: `Successfully loaded ${listItems.length} items`,
DetailsNewsListItemState : {
items: newsListItems,
columns: []
}
});
break;
case "Directory":
let directoryFactory = new DirectoryListItemFactory();
let directoryListItems = directoryFactory._getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
this.setState({
status: `Successfully loaded ${listItems.length} items`,
DetailsDirectoryListItemState : {
items: directoryListItems,
columns: []
}
});
break;
default :
break;
}
}
This is the place where I get the exception, the first switch case works fine, the second one doesnt, and I understand whats happening, getitems return ListItem[], but I am trying to assign the value to an AnnouncementListItem[]
However I am not sure how to fix it, as you could see the newslisitem extends ListItem, and I want to make this solution as generic as possible
Update,
Forgot this file
import { IListItem } from './models/IListItem';
import { INewsListItem } from './models/INewsListItem';
import { IDirectoryListItem } from './models/IDirectoryListItem';
import { IAnnouncementListItem } from './models/IAnnouncementListItem';
import {
IColumn
} from 'office-ui-fabric-react/lib/DetailsList';
export interface IFactoryMethodState{
type: string;
status: string;
DetailsListItemState: IDetailsListItemState;
DetailsNewsListItemState: IDetailsNewsListItemState;
DetailsDirectoryListItemState : IDetailsDirectoryListItemState;
DetailsAnnouncementListItemState : IDetailsAnnouncementListItemState;
}
export interface IDetailsListItemState {
columns: IColumn[];
items: IListItem[];
}
export interface IDetailsNewsListItemState {
columns: IColumn[];
items: INewsListItem[];
}
export interface IDetailsDirectoryListItemState {
columns: IColumn[];
items: IDirectoryListItem[];
}
export interface IDetailsAnnouncementListItemState {
columns: IColumn[];
items: IAnnouncementListItem[];
}
Aucun commentaire:
Enregistrer un commentaire