I have a function named copyItem, which accepts a generic constrained param T.
But when it is called with another generic type, ts emits the error as described in the title.
Function definition:
function copyItem<T extends { children: T[] }>(data: T): T {
return data
}
Test Code:
interface MyItem {
children: MyItem[]
}
function testCopyItem<T extends MyItem>(data: T) {
copyItem(data)
}
Got this error:
Argument of type 'T' is not assignable to parameter of type '{ children: T[]; }'.
Type 'MyItem' is not assignable to type '{ children: T[]; }'.
Types of property 'children' are incompatible.
Type 'MyItem[]' is not assignable to type 'T[]'.
Type 'MyItem' is not assignable to type 'T'.
'MyItem' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'MyItem'.ts(2345)
The workaround I came up with is to declare an extra generic type V, which extends T, and replace T with V in the code, demonstrated as below:
function copyItemV2<V extends T, T extends { children: T[] }>(data: V): V {
return data
}
Test OK Now:
// ok
function testCopyItem<T extends MyItem>(data: T) {
copyItemV2(data)
}
(The whole example can be found at TS Playground.)
But why?