|
| 1 | +=== tests/cases/compiler/callOfConditionalTypeWithConcreteBranches.ts === |
| 2 | +type Q<T> = number extends T ? (n: number) => void : never; |
| 3 | +>Q : Symbol(Q, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 0)) |
| 4 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 7)) |
| 5 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 7)) |
| 6 | +>n : Symbol(n, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 32)) |
| 7 | + |
| 8 | +function fn<T>(arg: Q<T>) { |
| 9 | +>fn : Symbol(fn, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 59)) |
| 10 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 1, 12)) |
| 11 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 1, 15)) |
| 12 | +>Q : Symbol(Q, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 0)) |
| 13 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 1, 12)) |
| 14 | + |
| 15 | + // Expected: OK |
| 16 | + // Actual: Cannot convert 10 to number & T |
| 17 | + arg(10); |
| 18 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 1, 15)) |
| 19 | +} |
| 20 | +// Legal invocations are not problematic |
| 21 | +fn<string | number>(m => m.toFixed()); |
| 22 | +>fn : Symbol(fn, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 59)) |
| 23 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 7, 20)) |
| 24 | +>m.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) |
| 25 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 7, 20)) |
| 26 | +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) |
| 27 | + |
| 28 | +fn<number>(m => m.toFixed()); |
| 29 | +>fn : Symbol(fn, Decl(callOfConditionalTypeWithConcreteBranches.ts, 0, 59)) |
| 30 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 8, 11)) |
| 31 | +>m.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) |
| 32 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 8, 11)) |
| 33 | +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) |
| 34 | + |
| 35 | +// Ensure the following real-world example that relies on substitution still works |
| 36 | +type ExtractParameters<T> = "parameters" extends keyof T |
| 37 | +>ExtractParameters : Symbol(ExtractParameters, Decl(callOfConditionalTypeWithConcreteBranches.ts, 8, 29)) |
| 38 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 11, 23)) |
| 39 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 11, 23)) |
| 40 | + |
| 41 | + // The above allows "parameters" to index `T` since all later |
| 42 | + // instances are actually implicitly `"parameters" & keyof T` |
| 43 | + ? { |
| 44 | + [K in keyof T["parameters"]]: T["parameters"][K]; |
| 45 | +>K : Symbol(K, Decl(callOfConditionalTypeWithConcreteBranches.ts, 15, 9)) |
| 46 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 11, 23)) |
| 47 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 11, 23)) |
| 48 | +>K : Symbol(K, Decl(callOfConditionalTypeWithConcreteBranches.ts, 15, 9)) |
| 49 | + |
| 50 | + }[keyof T["parameters"]] |
| 51 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 11, 23)) |
| 52 | + |
| 53 | + : {}; |
| 54 | + |
| 55 | +// Original example, but with inverted variance |
| 56 | +type Q2<T> = number extends T ? (cb: (n: number) => void) => void : never; |
| 57 | +>Q2 : Symbol(Q2, Decl(callOfConditionalTypeWithConcreteBranches.ts, 17, 7)) |
| 58 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 8)) |
| 59 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 8)) |
| 60 | +>cb : Symbol(cb, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 33)) |
| 61 | +>n : Symbol(n, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 38)) |
| 62 | + |
| 63 | +function fn2<T>(arg: Q2<T>) { |
| 64 | +>fn2 : Symbol(fn2, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 74)) |
| 65 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 13)) |
| 66 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 16)) |
| 67 | +>Q2 : Symbol(Q2, Decl(callOfConditionalTypeWithConcreteBranches.ts, 17, 7)) |
| 68 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 13)) |
| 69 | + |
| 70 | + function useT(_arg: T): void {} |
| 71 | +>useT : Symbol(useT, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 29)) |
| 72 | +>_arg : Symbol(_arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 22, 16)) |
| 73 | +>T : Symbol(T, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 13)) |
| 74 | + |
| 75 | + // Expected: OK |
| 76 | + arg(arg => useT(arg)); |
| 77 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 16)) |
| 78 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 24, 6)) |
| 79 | +>useT : Symbol(useT, Decl(callOfConditionalTypeWithConcreteBranches.ts, 21, 29)) |
| 80 | +>arg : Symbol(arg, Decl(callOfConditionalTypeWithConcreteBranches.ts, 24, 6)) |
| 81 | +} |
| 82 | +// Legal invocations are not problematic |
| 83 | +fn2<string | number>(m => m(42)); |
| 84 | +>fn2 : Symbol(fn2, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 74)) |
| 85 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 27, 21)) |
| 86 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 27, 21)) |
| 87 | + |
| 88 | +fn2<number>(m => m(42)); |
| 89 | +>fn2 : Symbol(fn2, Decl(callOfConditionalTypeWithConcreteBranches.ts, 20, 74)) |
| 90 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 28, 12)) |
| 91 | +>m : Symbol(m, Decl(callOfConditionalTypeWithConcreteBranches.ts, 28, 12)) |
| 92 | + |
| 93 | +// webidl-conversions example where substituion must occur, despite contravariance of the position |
| 94 | +// due to the invariant usage in `Parameters` |
| 95 | + |
| 96 | +type X<V> = V extends (...args: any[]) => any ? (...args: Parameters<V>) => void : Function; |
| 97 | +>X : Symbol(X, Decl(callOfConditionalTypeWithConcreteBranches.ts, 28, 24)) |
| 98 | +>V : Symbol(V, Decl(callOfConditionalTypeWithConcreteBranches.ts, 33, 7)) |
| 99 | +>V : Symbol(V, Decl(callOfConditionalTypeWithConcreteBranches.ts, 33, 7)) |
| 100 | +>args : Symbol(args, Decl(callOfConditionalTypeWithConcreteBranches.ts, 33, 23)) |
| 101 | +>args : Symbol(args, Decl(callOfConditionalTypeWithConcreteBranches.ts, 33, 49)) |
| 102 | +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) |
| 103 | +>V : Symbol(V, Decl(callOfConditionalTypeWithConcreteBranches.ts, 33, 7)) |
| 104 | +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) |
| 105 | + |
0 commit comments