Reputation: 713
I have a function which takes an array of objects which do not have an id property and return all those objects with an id property added to them.
const pickIdAndDocs = (arr) => {
return arr.map(doc => ({
id: 1,
...doc
}))
}
Now, for example if i have this interface
interface iUser {
name: string;
}
and an array containing values of type iUser
let users: iUser[] = [ {name: "John"}, {name: "Joe"} ];
How do i specify the return type of the function pickIdAndDocs, such that it returns an array where each item is an extended type of the input type it takes with an added id property
function pickIdAndDocs<T>(items : T[] ) : extendedT[];
This function can take an array of any type (will always be objects/key-value pairs), an return all items with an appended id property.
Or am i approaching this the wrong way? Thanks :)
Upvotes: 1
Views: 137
Reputation: 55866
Essentially we want to build up new type by combining two types. One with {id: number}
and another is whatever passed to the function. This exactly what intersection type
does. Assuming my interpretation of your problem is correct, I think this is what you want:
interface User {
name: string;
}
type WithId<T> = T & { id: number };
const pickIdAndDocs = <T,>(arr: T[]): WithId<T>[] => {
return arr.map((doc) => ({
id: 1,
...doc,
}));
};
let users: User[] = [{ name: "John" }, { name: "Joe" }];
const usersWithId = pickIdAndDocs(users);
// No warning!
usersWithId[0].id;
usersWithId[0].name;
// Warning: Property 'age' does not exist on type 'WithId<User>'.
usersWithId[0].age;
Here is the TS Playground link: https://tsplay.dev/ND5B4m
Upvotes: 4