Constante la momentul compilării în TypeScript?


Scriu o bibliotecă în TypeScript și vreau să o direcționez atât pentru Node, cât și pentru Browser. În acest moment rulez tsc de două ori cu două ținte diferite. Acea parte funcționează bine.

Totuși, o mică parte din codul meu este specifică țintei. Trebuie să pot să fac ceva de genul:

if(BUILD_TARGET === 'node') {
    // do something
} else {
    // do something else
}

Există vreo modalitate prin care pot să injectez aceste constante la timpul de compilare astfel încât să poată fi optimizate de tsc în sine, sau printr-o trecere prin UglifyJS (sau un astfel de instrument)?

Răspuns #1

Ceea ce se apropie cel mai mult de constantele la timpul de compilare în TypeScript sunt const enums - conform documentației, „spre deosebire de enum-urile obișnuite, ele sunt complet eliminate în timpul compilării”.

Acest lucru are însă un preț - cea mai mare avertizare este că enumerațiile const sunt incompatibile cu modul isolatedModules=true, care este adesea folosit de împachetatori.

De asemenea, Typescript nu va elimina codul mort, va trebui să folosești alt instrument pentru a elimina ulterior ramura if (0 === 1).

Veți avea nevoie de două fișiere tsconfig.json diferite, fiecare va include un fișier care va avea o definiție diferită pentru același tip enum.

tsconfig.browser.json

{
  "files": [
    "t.ts",
    "target-enum-browser.d.ts"
  ]
}

target-enum-browser.d.ts

declare module 'target-enum' {
    export const enum Target { Node, Browser, Current = Browser }
}

tsconfig.node.json

{
  "files": [
    "t.ts",
    "target-enum-node.d.ts"
  ]
}

target-enum-node.d.ts

declare module 'target-enum' {
    export const enum Target { Node, Browser, Current = Node }
}

t.ts

import {Target} from 'target-enum';

if (Target.Current === Target.Browser) {
    console.log('browser');

} else if (Target.Current === Target.Node) {
    console.log('node');
    
} else {
    console.log('?');
}

compilat cu tsc --project tsconfig.browser.json

"use strict";
exports.__esModule = true;
if (1 /* Current */ === 1 /* Browser */) {
    console.log('browser');
}
else if (1 /* Current */ === 0 /* Node */) {
    console.log('node');
}
else {
    console.log('?');
}

compilat cu tsc --project tsconfig.node.json

"use strict";
exports.__esModule = true;
if (0 /* Current */ === 1 /* Browser */) {
    console.log('browser');
}
else if (0 /* Current */ === 0 /* Node */) {
    console.log('node');
}
else {
    console.log('?');
}