Description
TypeScript Version: 3.7.5
Search Terms:
Generic recursion
Subtype
Also, already asked elsewhere
Code
export type TestProxy<TARGET> = (
TARGET extends Array<any> ? TestArray<TARGET> :
TARGET
)
type TestArray<TYPE extends Array<any>> = {
[key in (keyof TYPE & number)]: TYPE[key];
}
& Omit<TYPE, keyof Array<any>> // Special case for Array extensions
& {
length: any, push: any, concat: any,
join: any, reverse: any, shift: any, slice: any,
sort: any, splice: any, unshift: any, indexOf: any,
lastIndexOf: any, every: any, some: any, forEach: any,
filter: any, reduce: any, reduceRight: any, find: any,
findIndex: any, fill: any, copyWithin: any, [Symbol.iterator]: any,
entries: any, keys: any, values: any, [Symbol.unscopables]: any,
includes: any, flatMap: any, flat: any,
// pop: any, // CASE A everything works
pop(): TestProxy<TYPE[number]>; // CASE B
map<OUT>(cb: (it: TYPE[number], index: number, array: TestArray<TYPE>) => OUT): TestProxy<Array<OUT>>;
}
type TYPE = Array<string> & { extraField: string };
const thing: TYPE = null as any as TestProxy<TYPE>; // Works in CASE A
const hat: string = "hat" as TestProxy<"hat">; // Always works
function proxyMe<TYPE>(target: TYPE): TestProxy<TYPE> {
return target as any; // imagine proxy
}
const obj: { arr: number[][] } = { arr: [] };
const testArr = proxyMe([[1], [2], [3]]);
obj.arr = testArr; // CASE A: works -- CASE B: Type 'TestArray<U[]>' is not assignable to type 'U[]
Expected behavior:
In Case A, it is valid to say TYPE === TestProxy<TYPE>
for all types. Therefore, having pop()
return TestProxy<TYPE>
in Case B should be valid.
Actual behavior:
In Case A, everything works.
In Case B, this error arises (see playground link)
Type 'TestArray<number[][]>' is not assignable to type 'number[][]'.
The types returned by 'pop()' are incompatible between these types.
Type 'TestArray<number[]> | undefined' is not assignable to type 'number[] | undefined'.
Type 'TestArray<number[]>' is not assignable to type 'number[] | undefined'.
Type 'TestArray<number[]>' is not assignable to type 'number[]'.
The types returned by 'map(...)' are incompatible between these types.
Type 'TestArray<U[]>' is not assignable to type 'U[]'
Playground Link:
Playground Link
Related Issues:
I've heard there are limitations to Generics that have been found elsewhere