I am trying to use PnP in an SPFx webpart, and I'd like to add typings to the return value of a function, that'll return a list of list items. How do we handle this in PnP? I can't find a reference to this on the PnP site.
For example I have this code:
//Not sure what the return type will be here.
private async getOptions(pollName: string): Promise<PnPListItems> {
let itemsReq = sp.web.lists.getByTitle(this.properties.listName).items
let items = await itemsReq
return items;
}
the way to do it is...
let items = await sp.web.lists.getByTitle(this.properties.listName).items .select("Id", "Title",...).get<[{ Id: string, Title: string, ... }]>();
Or the get part can be a pre-defined interface like
let items = await sp.web.lists.getByTitle(this.properties.listName).items .select("Id", "Title",...).get<[IMyListItem]>();
It is in the docs somewhere, because that's how I figured out how to do it, but at the moment I can't put my finger on it.
Were you looking for Entity Merging?
https://pnp.github.io/pnpjs/sp/docs/entity-merging/
@juliemturner, you have a small typescript issue/typo in your samples, literally, you defined not the array as a return object but a single value tuple which will always be an array with one value in this case. And items[0].Title will be ok, but items[1].Title will be an incorrect statement due to typings rules.
Should be:
list.items.select('Id', 'Title').get<{ Id: number; Title: string; }[]>() //...
// or
list.items.select('Id', 'Title').get<IMyListItem[]>() //...
Yes you鈥檙e right @koltyakov .. I modified my example from a copy paste so it would be shorter and got my brackets moved around. Thanks for the correction
@koltyakov @juliemturner @sympmarc So for my method signature, using what @sympmarc mentioned here: https://pnp.github.io/pnpjs/sp/docs/entity-merging/ .. can't I mark the return type for the method as:
import { sp, spODataEntityArray, Item } from "@pnp/sp";
private async getOptions(pollName: string): Promise<Item[]> {
let items = await sp.web.lists.getByTitle(this.properties.listName).items
return items;
}
or is it a MUST to use spODataEntityArray & spODataEntity?
I don鈥檛 use the method mentioned by @sympmarc but you certainly could... that said you鈥檙e still missing part of the call.. after items you need .get and then implement either my suggestion as corrected by @koltyakov or as the example in the docs shows.
What @juliemturner said. I鈥檝e been using the Entity Merging approach because to me, it feels like it simplifies the code. Your interface should match the fields in your select for it to make sense.
@Danielaroc,
You still miss .get so you won't get any actual data as a result.
If only data should be returned no entity merging is required at all.
E.g.:
1. Getting only data:
import { sp } from '@pnp/sp';
interface MyProps {
Id: number;
Title: string;
}
const getOptions = (): Promise<MyProps[]> => { // define here or in .get<> generic
const list = sp.web.lists.getByTitle('CustomList');
return list.items.select('Id,Title').get<MyProps[]>(); // this is optional
// as promise method above is already typed
}
getOptions().then(console.log);
the result is only OData response:

2. Entity merging:
import { sp, spODataEntityArray, Item } from '@pnp/sp';
interface MyProps {
Id: number;
Title: string;
}
const getOptions = (): Promise<(Item & MyProps)[]> => {
const list = sp.web.lists.getByTitle('CustomList');
return list.items.select('Id,Title').get(spODataEntityArray<Item, MyProps>(Item));
// entity merging actually changes results
// not only data is available but an actual Items
// which can be chained with other REST API actions available for items
}
getOptions().then(console.log);
the result is:

@koltyakov Oh I got it now. Thanks for the detailed response, this really helps!
@sympmarc @juliemturner Thanks for the tips, the sample provided and the entity merging will definitely help me write better code.
Most helpful comment
@Danielaroc,
You still miss
.getso you won't get any actual data as a result.If only data should be returned no entity merging is required at all.
E.g.:
1. Getting only data:
the result is only OData response:
2. Entity merging:
the result is: