typescript4.0 - Kommauttryck typescript 4.4.x-utdata


Jag har följande inmatning:

import {onMediaChangeSubscribe} from '../functions/doOnMediaChange'

export class ActionButton extends ElementBase {
    mount(){
        onMediaChangeSubscribe(this.render)
    }
}

Utdata från TypeScript 4.3.x är:

doOnMediaChange_1.onMediaChangeSubscribe(this.render);

Och TypeScript 4.4.x gör följande:

(0, doOnMediaChange_1.onMediaChangeSubscribe)(this.render);

Vad i helvete??? Min fråga besvaras delvis här: JavaScript-syntax (0, fn)(args), men jag skulle vilja klargöra.

Varför finns det en sådan förändring i TypeScript?


Minimalt reproduktionsexempel:

a.ts
export function doTheThing(){}
b.ts
import {doTheThing} from './a'

doTheThing()

b.ts kompileras till:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var a_1 = require("./a");
(0, a_1.doTheThing)();

Använd tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "declaration": true,
    "strict": true,
    "noImplicitAny": false,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "downlevelIteration": true
  },
  "exclude": [
    "node_modules"
  ]
}

Svar #1

Denna förändring implementerades i microsoft/TypeScript#44624 som en lösning på microsoft/TypeScript#35420, och släpptes med TypeScript 4.4. (Observera att det fanns ett tidigare försök till fix i microsoft/TypeScript#35877 men detta återställdes i microsoft/TypeScript#43993 innan det släpptes.)

Som svaret på den andra frågan förklarar, är skillnaden mellan foo.bar() och (0, foo.bar)() att this-kontexten för det förstnämnda är foo, medan den för det sistnämnda är undefined (i strikt läge, eller globalt objekt i slarvigt läge). foo.bar() behandlar bar som en metod av foo, medan (0, foo.bar)() behandlar bar som en funktion orelaterad till foo.

Beroende på TypeScripts modulmål kommer den genererade Javascript-koden att lägga importerade saker i ett objekt, så

import {onMediaChangeSubscribe} from '../functions/doOnMediaChange'

kan utsändas som

const doOnMediaChange_1 = require("../functions/doOnMediaChange")

Och sedan behöver alla referenser till onMediaChangeSubscribe skickas ut som doOnMediaChange_1.onMediaChangeSubscribe.

När du anropar en importerad funktion vill du att den ska agera som en funktion och inte som en "metod" av modulen du importerar. Tja, mycket av tiden finns det ingen skillnad, men om kroppen av den importerade funktionen råkar referera till this, vill du verkligen att this ska vara undefined och inte doOnMediaChange_1, annars kommer det inte att vara ekvivalent med beteendet hos inbyggda moduler.

Det var i huvudsak problemet i microsoft/TypeScript#35420. Lösningen är helt enkelt att universellt omsluta anrop till importerade funktioner med kommateckensoperatorn, som du har sett.

Relaterade artiklar