1describe("unittests:: evaluation:: externalModules", () => { 2 // https://github.com/microsoft/TypeScript/issues/35420 3 it("Correct 'this' in function exported from external module", async () => { 4 const result = evaluator.evaluateTypeScript({ 5 files: { 6 "/.src/output.ts": ` 7 export const output: any[] = []; 8 `, 9 "/.src/other.ts": ` 10 import { output } from "./output"; 11 export function f(this: any, expected) { 12 output.push(this === expected); 13 } 14 15 // 0 16 f(undefined); 17 `, 18 "/.src/main.ts": ` 19 export { output } from "./output"; 20 import { output } from "./output"; 21 import { f } from "./other"; 22 import * as other from "./other"; 23 24 // 1 25 f(undefined); 26 27 // 2 28 const obj = {}; 29 f.call(obj, obj); 30 31 // 3 32 other.f(other); 33 ` 34 }, 35 rootFiles: ["/.src/main.ts"], 36 main: "/.src/main.ts" 37 }); 38 assert.equal(result.output[0], true); // `f(undefined)` inside module. Existing behavior is correct. 39 assert.equal(result.output[1], true); // `f(undefined)` from import. New behavior to match first case. 40 assert.equal(result.output[2], true); // `f.call(obj, obj)`. Behavior of `.call` (or `.apply`, etc.) should not be affected. 41 assert.equal(result.output[3], true); // `other.f(other)`. `this` is still namespace because it is left of `.`. 42 }); 43 44 it("Correct 'this' in function expression exported from external module", async () => { 45 const result = evaluator.evaluateTypeScript({ 46 files: { 47 "/.src/output.ts": ` 48 export const output: any[] = []; 49 `, 50 "/.src/other.ts": ` 51 import { output } from "./output"; 52 export const f = function(this: any, expected) { 53 output.push(this === expected); 54 } 55 56 // 0 57 f(undefined); 58 `, 59 "/.src/main.ts": ` 60 export { output } from "./output"; 61 import { output } from "./output"; 62 import { f } from "./other"; 63 import * as other from "./other"; 64 65 // 1 66 f(undefined); 67 68 // 2 69 const obj = {}; 70 f.call(obj, obj); 71 72 // 3 73 other.f(other); 74 ` 75 }, 76 rootFiles: ["/.src/main.ts"], 77 main: "/.src/main.ts" 78 }); 79 assert.equal(result.output[0], true); // `f(undefined)` inside module. Existing behavior is incorrect. 80 assert.equal(result.output[1], true); // `f(undefined)` from import. New behavior to match first case. 81 assert.equal(result.output[2], true); // `f.call(obj, obj)`. Behavior of `.call` (or `.apply`, etc.) should not be affected. 82 assert.equal(result.output[3], true); // `other.f(other)`. `this` is still namespace because it is left of `.`. 83 }); 84});