Skip to content

Preprocessor directives proposal #3670

Closed
@tinganho

Description

@tinganho

This proposal is based on C# spec for preprocessor directives. https://msdn.microsoft.com/en-us/library/aa691099(v=vs.71).aspx

Problem

Some JS applications are used in multiple platforms. I.e. Cordova/Phonegap for mobile platforms, isomorphic applications for server-side and client-side rendered applications. And those platforms are hosting different set of API:s. We use import statements to import and use a host's API. A developer must guard one platform's API from an another.

Before ES6 modules one could guard an import using if statements:

if (IOS_PLATFORM) {
   var http = require('./http-ios');
}

ES6 modules prohibits conditional imports, because the import statements must be a file-level statement. So we can't do:

if (IOS_PLATFORM) {
   import {something} from './something';
}

Solution

We can solve the above problem with preprocessor directives. And here is one example of the problem above solved with a preprocessor directives:

#if IOS_PLATFORM
import {http} from './http';
#endif

Proposed directives:

define directive

#define {VARIABLE} [{VALUE}]

The define directive defines a global flag or global variable. When a value is specified it is regarded as a preprocessor variable.

flow directives

#if
#elif
#else
#endif

It must exist at least one #if and at maximum one #else directive per control-flow statement. A directive must be closed with an #endif directive. You can also nest preprocessor control-flow statements in each other. In addition to hosting TS code, a control-flow statement's body can also host #define and #error directive that defines additional behaviour for the preprocessor.

Each control-flow branch is scoped from other sibling branches. So the below example will yield an access undefined error:

#if branch1
var test = "string";
#elif branch2
test.length; // error
#endif
test.length; // no error

preprocessor operators:

==
!=
&&
||

These should work as comparison operators in TS and JS along with parens ().

error directive

#error {MESSAGE}

The error directive is to help guiding developers to set right set of flags and values. In some cases two disjoint branches aren't supposed to be joined. An example is given below:

#if IOS_PLATFORM && ANDROID_PLATFORM
    #error "Cannot set two platform flags"
#endif

Or when a preprocessor variable is set to an invalid value:

#if PLATFORM == windows
    #error "Cannot set platform preprocessor variable to windows."
#endif

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions