Here's an alternative method:
const modifyList<T extends number[]>(
list: [...{ [I in keyof T]: Altered<T[I]> }]
) {
return list.map((item) => ({ ...item, changed: true })) as
{ [I in keyof T]: Modified<T[I]> };
}
The concept behind modifyList()
is to introduce a generic approach with the paramenter T
, which represents a tuple composed of numerical literal types corresponding to the indexes of the elements in the input list
. So if you invoke modifyList([1, 2, 3])
, T
will be [1, 2, 3]
.
Subsequently, the type of the incoming list
is transformed into a mapped tuple where each element T[I]
(the I
th item within the T
tuple) is converted to Identified<T[I]>
, while the outcome consists of a mapped tuple that converts each element T[I]
to Modified<T[I]>
.
It's worth noting that the type of list
doesn't exclusively adhere to the mapped format
{ [I in keyof T]: Identified<T[I]> }
, but instead has been encased in a
variadic tuple represented by
[...{ [I in keyof T]: Identified<T[I]> }]
; this particular setup aids the compiler in favoring inferred tuple types over disordered arrays. If not structured in such a way,
modifyList([1, 2, 3])
might lead to an inference of
("1" | "2" | "3")[]
for
T
, which may deviate from your intentions.
Similarly, it was necessary to utilize a type assertion to notify the compiler that
list.map(item => ({...item, changed: true}))
matches the intended output type. The compiler cannot autonomously deduce or verify this aspect. Essentially, the compiler lacks the capability to discern that
list.map(...)
corresponds precisely to your description. Refer to this relevant answer for further insights on this constraint.
To ensure that it operates as expected:
let one: Identified<1> = { index: 1 };
let two: Identified<2> = { index: 2 };
let three: Identified<3> = { index: 3 };
let modifiedList = modifyList([one, two, three]);
// let modifiedList: [Modified<1>, Modified<2>, Modified<3>]
let oneModified = modifiedList[0];
// let oneModified: Modified<1>
All seems well!
Access playground link for code