Skip to content

Write strings and type information to the console at compile time #29937

Closed as not planned
@pineapplemachine

Description

@pineapplemachine

Search Terms

compile time, logging, pragma

Suggestion

Add some statement which outputs a message to the console when running tsc and which is not emitted in the JavaScript output. It should be possible to log literal values such as strings as well as information about types and generic parameters.

Use Cases

I've written a lot of code in D and it's probably my favorite language to work with, in spite of its flaws. D has the most wonderful, mature, and usable template system of any language I know of. (For the unaware: Templates are kind of like generics, except if generics could accept values and expressions computable at compile-time, not only types. Templates are like generics except more.)

One of the most essential features that helps keep D's mammoth of a template system so useable looks like this: pragma(msg, "My compiler message");. When the compiler reaches this code, it will log out the string to the console along with its other status messages.

Of course, logging string literals is only a small part of its usefulness. What's really important is the countless times that I've used this tool to output information about template parameters I'm confused about. What's T here? Let me add in a pragma(msg, T);... Aha, T is a uint. No wonder my code doesn't work. Fix, fix... Problem solved.

I have felt the need for a feature like this in TypeScript so many times, particularly as a tool to help me to better understand compiler errors rendered opaque by T identifiers all over the place, or to figure out what the heck ReturnType<my_function_with_a_non_trivial_inferred_return_type> is so that I can actually identify and refer to this zany type in other places.

Note that when this logging statement is contained within a parameterized function or type or etc., the ideal behavior is for it to log its message once for every different combination of generic parameters that the enclosing scope receives.

Examples

The first mechanism I can think of is to add a new standard identifier which is used like a parameterized type. I don't know enough about the language innards to say if this is really an especially viable solution. I'm not really attached to this particular syntax proposal. But it's an idea.

ConsoleMessage<"This is a statically-known message string which will appear during compilation">;
ConsoleMessage<"Please tell me all about this type:">;
ConsoleMessage<T>;
function myFunction<T>() {
    ConsoleMessage<"This message will be outputted exactly three times">;
    ConsoleMessage<T>;
}

myFunction<boolean>(); // Logs for T = boolean
myFunction<number>(); // Logs for T = number
myFunction<string>(); // Logs for T = string
myFunction<string>(); // Does not log

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals. (It would go a long way to actually accomplishing goal 5...)

Metadata

Metadata

Assignees

No one assigned

    Labels

    SuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions