Skip to content

suggestion to inline const keywords for ES5 #3964

Closed

Description

@Gambero81

it would be great to transpile const declaration with inline value when target is ES5 (as already Done with const enum), so it will prevent to include useless javascript.
An example:

const A = "myConstValue";
alert(A);
// generated js code:
alert("myConstValue" /* A */)

Another example:
module MyConstMudule
{
   export const A = "myConstValue";
}
alert(MyConstModule.A);
// generate js code:
alert("myConstValue" /* MyConstModule.A */);

what do you think?

Activity

  1. added
    SuggestionAn idea for TypeScript
    Needs ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.
    and removed on Jul 21, 2015
  2. mhegazy commented on Jul 21, 2015

    @mhegazy
    Contributor

    How does it get emitted in a .d.ts for instance? what if the const value is dependent on non-const values or has side effects, e.g.

    declare function foo():number;
    
    const x = foo();
    
    console.log("here is x: " + x);
    console.log("again: " + x);

    the const enums are restricted to only constant expressions which is different from the const semantics; so we can not copy the implementation, we need to come up with a different proposal.

  3. dead-claudia commented on Jul 23, 2015

    @dead-claudia

    Suggestion: limit that scope to what enums can handle. And FWIW, in my enum proposal, I already created an algorithm to figure out most of what's safe to replace. It's intentionally limited to booleans, numbers, strings, null, and undefined, and function calls do not count. It's towards the end of this section.

    As for functions themselves, there's a lot of bikeshedding to do to figure out how, if possible, to judge and/or enforce if a function is truly immutable or not.

    If functions are explicitly designated as immutable, it's not hard to verify those functions as immutable. And for languages that are immutable by default, it's even easier. Inferring if a function is mutable is easy - it's a matter of "Is there any way this can cause side effects?". Merely an assignment to a reference the function didn't create is enough to say yes (variable outside a closure, assignment to member, etc.).

    As for inferring immutability, that's probably impossible to do completely. Even in C/C++, as advanced as their compilers are, they still can only partially make that judgement, even with the static types and explicit reference vs value, and even without lexical closures (in the case of C). This is still a CS research topic in trying to figure how far they can. As for why it's likely impossible to fully infer this, try to factor in branch checking or recursion (which requires branch checking) into the process. It would require partially running the program to figure some parts out. You'd have to build a Turing-complete scope checker to figure that out.

  4. mhegazy commented on Jul 23, 2015

    @mhegazy
    Contributor

    This is then just constant propagation. it is not strictly tied to const declarations or enums. we will have to allow constant expressions to emitted in .d.ts files (which today they do not) to enable this feature.

  5. dead-claudia commented on Jul 23, 2015

    @dead-claudia

    Mohamed Hegazy (@mhegazy) I'm aware of that. That's basically what the suggestion would entail, just as the enum situation currently does. I am fairly neutral on this, although IMHO it would be better for the compiler to allow some sort of pluggable transform like what Babel does, or a similar framework to allow that. The API exists to do the manipulations, but there isn't much of an ecosystem to go with it.

  6. TazmanianDI commented on Apr 10, 2018

    @TazmanianDI

    This seems like something that could benefit styled components which use template literals for building CSS. If this change supported template literals that would be great.

    For example:

    const VALUE = 10;
    const aString = `A ${VALUE} B`;

    Could be output as (although this might break tagged template literals).

    const aString = `A ` + 10 + ` B`;

    Or potentially just

    const aString = `A 10 B`;

  7. dead-claudia commented on Apr 10, 2018

    @dead-claudia

    Damon Lundin (IBM) (@TazmanianDI) This is unsafe for three scenarios:

    1. Symbols (they are not coercible)
    2. Reference types (.toString is called)
    3. Tagged template literals (as you already mentioned)

    In all other use cases, this is a safe thing to do. Conveniently, constant propagation works only for literals, and all literals except objects and functions are primitives, so the only problematic construct would be with tagged template literals.

    Note that this could increase code size, and so it should be disabled by default.

  8. G-Rath commented on Nov 22, 2018

    @G-Rath

    I might be missing the point here a little, but why not just use the same syntax with enums: const type?

    This is what I'm trying to do:

    // index.d.ts
    export declare namespace API {
        namespace ListUsers {
            const type ENDPOINT = '/users';
            const type METHOD = 'GET';
        }
    }
    
    // api.ts
    const listUsers = () => Axios.request({
        baseUrl: process.env.API_BASE_URL,
        method: API.ListUsers.METHOD,
        url: API.ListUsers.ENDPOINT
    }).then(response => response.data);
    

    I can do this just fine with const enum, but I'd not like to make single-value enums.
    Let me know if this is actually a separate feature request 😄

  9. dead-claudia commented on Nov 23, 2018

    @dead-claudia

    Gareth Jones (@G-Rath) Not a fan of using const type for a value...it seems incredibly off and weird. Not TS team obviously, but I don't think they'll be a fan of it either.

  10. G-Rath commented on Nov 23, 2018

    @G-Rath

    @isiahmeadows fair enough - I agree it's not the most ideal or best looking, but it does at least match const enum, and it's unused syntax right now...

    It's a least a starting proposal 😂

  11. TazmanianD commented on Nov 26, 2018

    @TazmanianD

    Gareth Jones (@G-Rath) I do like the idea of having a means to tell the compiler it's safe to fully inline certain constants. That might be a way to get around the unsafe cases.

  12. manferlo81 commented on Jun 2, 2019

    @manferlo81

    IMHO this is a good feature, if I get it right it would be like #define in C++ or inline in Pascal.

    Sometimes you need to use a value in a couple of different places but it does not worth to declare a constant for it, so the compiler should just copy the value to wherever the "inline constant" has been used.

    example
    inline const NUM = 1.53676758;
    const result = inputVar / NUM + NUM;

    should compile to...

    const result = inputVar / 1.53676758 + 1.53676758;

    It avoids mistakes if and when you need (for some reason) to tweak the value of the "inline constant".

  13. dragomirtitian commented on Jun 2, 2019

    @dragomirtitian
    Contributor

    This is a pretty old ticket so the current template might not have been in place, but doesn't it violate this requirement from the current template:

    • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  14. dead-claudia commented on Jun 3, 2019

    @dead-claudia

    Titian Cernicova-Dragomir (@dragomirtitian) Not entirely - constant inlining only affects emit, not runtime semantics (unless you care about Function.prototype.toString behavior). Also, that general philosophy was itself held to some extent when the issue was first created, so it's been through quite a bit of discussion already. They aren't entirely against runtime features in theory, just the runtime side is complete enough that there's virtually nothing left to add that's genuinely useful and 99.9999% of valid feature requests are just about implementing various ES proposals. So although that checkbox does have a reason, there are a few limited scenarios (like this) where you can justify changes to runtime and/or emit behavior.

  15. feeddageek commented on Oct 8, 2019

    @feeddageek

    A new declaration syntax for which Typescript would enforce having a constant expression as a RHS and that would be inlined should be added.

    Something like:

    const const MAX_ROW_COUNT = 5;
    // or 
    inline MAX_ROW_COUNT = 5;

    const const is nice because it doesn't create a new keyword, but inline is less verbose
    inline const is also an interesting option that could allow future inlining of other things.

    Currently we have to do this because exported const name can't be minified.

    export const enum MAX {
        ROW_COUNT = 5
    }

    It is really silly.

  16. kajmagnus commented on Sep 19, 2020

    @kajmagnus

    Emeric Garon (@feeddageek) wrote:

    Something like:

    const const 

    I was thinking about that me too — then I thought it would be confusing to people learning Typescript.

    I like this:

    inline const STH = ...
    inline enum EnumName = { ...  }
    

    Is inline enum more welcoming & self explanatory, to people learning Typescript, than const enum?

    What if having inline be a keyword only in the variable / stuff declarations part of the program? But still allowing variables and functions to have the name "inline"? for backw compatibility. (So that let inline = true would still work)

    At the same time, the following is a somewhat ok workaround?

    const enum CONSTANT = { _: the-value }
    
    // And use like so:
    doTheThings(CONSTANT._)
    
  17. added
    Out of ScopeThis idea sits outside of the TypeScript language design constraints
    and removed
    Needs ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.
    on Sep 21, 2020
  18. RyanCavanaugh commented on Sep 21, 2020

    @RyanCavanaugh
    Member

    This violates the "does the same thing as JS" principle pretty hard and is getting close to type-directed emit, so I think given the feedback so far and the risk of the feature, it's safe to say this isn't happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Out of ScopeThis idea sits outside of the TypeScript language design constraintsSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions