I have a TS problem about using generics in Function. In summary, I would like to write a function, which accepts a array of objects which has a specific interface. And in my function, I do something, and add a new property named 'children' on each item in array. How can I write TS type on this function? When I use this function, I will know the return value has the same type of input array of object, and., has children property also. I try to use generics, but not work.
Any help is greatly appreciated!!!
below is my example code.
// src array
const src = [
{ id: 3, parentId: 2 },
{ id: 2, parentId: 1 },
{ id: 1 },
{ id: 4 },
{ id: 5, parentId: 4 },
{ id: 6, parentId: 8 },
{ id: 7, parentId: 9 },
{ id: 7, parentId: 9, title : 'ssss' },
];
interface Src {
id:number;
parentId? : number | string;
title? : string
}
// I use generics, but return value cant has children on each items of array
function test<T extends Src>(arr : Array<T>) :Array<T> {
for(let i=0;i<arr.length;i++){
// add children here
arr[i].children = {xxxxx}
}
return arr;
}
let a = test(src)
// I want ts can tell me, each items in res array, has the same type of src, but also be added children property
let res = test(src)
You should really use some array utility method like map
to achieve this
function test<T extends Src>(arr : Array<T>) {
return arr.slice().map(item => ({
...item,
children: { xxx: "XXX" }
}))
}
this will add children: {xxx: "XXX}
to every element and return the modified array with the correct type.
let srcWithChildren = test(src)
src[0].children // <--- Error.Property doesn't exist.
srcWithChildren[0].children // <--- OK. Typescript knows about the new property.
const src = [ { id: 3, parentId: 2 }, { id: 2, parentId: 1 }, { id: 1 }, { id: 4 }, { id: 5, parentId: 4 }, { id: 6, parentId: 8 }, { id: 7, parentId: 9 }, { id: 7, parentId: 9, title: 'ssss' }, ]; function test(arr) { return arr.slice().map(item => ({...item, children: { xxx: "XXX" } })) } console.log(test(src))
Aside of @soffyo's answer, to adjust the return type to also contain the new property "children", you'll want to create a new type.
This could be done inline
function test<T extends Src>(arr : Array<T>) :Array<T & { children: object }> {
for(let i=0;i<arr.length;i++){
// add children here
arr[i].children = {xxxxx}
}
return arr;
}
Or via type aliasing
type SrcWithChildren = Src & { children: object };
function test<T extends Src>(arr : Array<T>) :Array<SrcWithChildren> {
for(let i=0;i<arr.length;i++){
// add children here
arr[i].children = {xxxxx}
}
return arr;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.