Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript compile-time constants?

Tags:

typescript

I'm writing a library in TypeScript and I want to target both Node and Browser. Right now I'm running tsc twice with two different targets. That part is working OK.

However, a tiny portion of my code is target-specific. I need to be able to do something like:

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

Is there any way I can inject these constants at compile-time so that they can either be optimized away by tsc itself, or via a pass through UglifyJS (or some such tool)?

like image 789
mpen Avatar asked Jun 16 '17 23:06

mpen


People also ask

What are compile time constants?

A compile-time constant is a value that is computed at the compilation-time. Whereas, A runtime constant is a value that is computed only at the time when the program is running. 2. A compile-time constant will have the same value each time when the source code is run.

Does TypeScript compile time?

Yes. In fact, other than a very small aspect related to enum s, TypeScript doesn't exist at runtime at all. TypeScript compiles to JavaScript, which is a dynamically-typed language.


1 Answers

The closest thing to compile-time constants in typescript are const enums - according to the documentation, "Const enum members are inlined at use sites". Typescript won't do dead code elimination, you will have to use some other tool to remove if (0 === 1) branch afterwards.

You will need two different tsconfig.json files, each will include a file that will have a different definition for the same enum type.

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('?');
}

compiled with 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('?');
}

compiled with 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('?');
}
like image 166
artem Avatar answered Nov 16 '22 01:11

artem