Skip to content

Enum literal cannot contain concatenated string #20784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
evmar opened this issue Dec 19, 2017 · 7 comments
Closed

Enum literal cannot contain concatenated string #20784

evmar opened this issue Dec 19, 2017 · 7 comments
Labels
Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@evmar
Copy link
Contributor

evmar commented Dec 19, 2017

TypeScript Version: 2.7.0-dev.20171216 and older

Code

enum Test {
  A = "a very long string value, such that you want to make it " +
    "span multiple lines to meet some column limit"
}

Expected behavior:
Accepted.

Actual behavior:
error TS2352: Type 'string' cannot be converted to type 'Test'.

Adding some 'as Test' annotation didn't seem to work.

Workarounds:

  • put it all on one very long line
  • wrap in parens, add an "as any"
@DanielRosenwasser DanielRosenwasser added In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Dec 19, 2017
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Dec 19, 2017

Out of curiosity, how are you currently planning on using the multiline enums? Something long enough that you hope nobody accidentally types it? Or is this just an unfortunate case of deep indentation?

@evmar
Copy link
Contributor Author

evmar commented Dec 19, 2017

We have code that uses enums for collections of long string constants. Not sure if it's the right use of enums though.

E.g. something like:

enum CompilerError {
  BAD_IMPORT: "bad import {}. try doing blah blah blah " +
    "or consult documentation at blah blah blah and so on"
}

Note that it's not exactly multiline (we want the resulting string to have no embedded newlines) so we can't use backticks for a multiline string. We just have multiple lines with a + in the middle for code style reasons (column limit).

@rozzzly
Copy link

rozzzly commented Jan 5, 2018

Enums are probably not the best suited for this. Here is what I would do.

export type ERROR_ONE = 'ERROR_ONE';
export const ERROR_ONE: ERROR_ONE = 'ERROR_ONE';

export type ERROR_TWO = 'ERROR_TWO';
export const ERROR_TWO: ERROR_TWO = 'ERROR_TWO';

export type ERROR_IDs = (
    | ERROR_ONE
    | ERROR_TWO
);

export const ERROR_MESSAGES: { [E in ERROR_IDs]: string; } = {
    [ERROR_ONE]: 'long ERROR_ONE message',
    [ERROR_TWO]: 'long ERROR_TWO message'
};

function getMessage(errorID: ERROR_IDs): string {
      return ERROR_MESSAGES[errorID];
}

console.log(getMessage (ERROR_ONE)); // $> long ERROR_ONE message

Neat things:

You will get completions

getMessage( ** here ** )

Plus, if you define add a new ERROR to ERROR_IDs but not ERROR_MESSAGES, the compiler will throw a fit.

This is basically how I type my redux actions. It's definitely verbose, but it gets the completions/type checking so I don't mind a little copy pasta.

@evmar
Copy link
Contributor Author

evmar commented Jan 5, 2018 via email

@rozzzly
Copy link

rozzzly commented Jan 5, 2018

I agree. But enums in TypeScript are kinda meh. There have been like 100+ issues opened about enums,
seeking for different functionality but they really haven't evolved much since they first debuted.

Best suggestion I can give is to write a script (or snippet for your prefered IDE) to generate that boilerplate for you. @chriseppstein just made an interesting suggestion here: #20898 (comment) which could also be compatible with string literals and would bring that 7 down to a 3. Not ideal, but eh

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Jan 30, 2018
@RyanCavanaugh RyanCavanaugh added this to the Community milestone Jan 30, 2018
@RyanCavanaugh RyanCavanaugh added the Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". label Jan 30, 2018
@RyanCavanaugh
Copy link
Member

Accepting PRs for this one. Should be reasonably straightforward as similar mechanics are already in place for numeric enum computations.

@mhegazy mhegazy modified the milestones: Community, TypeScript 2.9 Apr 21, 2018
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Apr 21, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Apr 21, 2018

thanks @Kingwl!

@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants