Skip to content
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

[Typescript] enum as const: add support const assertions from TypeScript 3.4 #3569

Merged
merged 2 commits into from
Mar 8, 2020

Conversation

DragorWW
Copy link
Contributor

TypeScript 3.4 introduces a new construct for literal values called const assertions. Its syntax is a type assertion with const in place of the type name (e.g. {} as const)

Example:

// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;

Read more about const assertions in:

This PR add parameter enumAsConst for generate enum like object literals

enum MyEnum {
  A_B_C
  X_Y_Z
  _TEST
  My_Value
}

output

export const MyEnum = {
  ABC: 'A_B_C',
  XYZ: 'X_Y_Z',
  Test: '_TEST',
  MyValue: 'My_Value'
} as const;
export type MyEnum = typeof MyEnum[keyof typeof MyEnum];

enum as const pattern allow usage string literal Playground Link;

PS:
I think constEnums, enumsAsTypes and enumAsConst need replace to enum: 'enum' | 'const enum', 'object const'

@dotansimha
Copy link
Owner

Hi @DragorWW !
Thank you for this PR. We currently have constEnums, how is that different? it seems like the output will be the same?

@DragorWW
Copy link
Contributor Author

DragorWW commented Mar 3, 2020

@dotansimha thanks for the answer

const enums works in the same way as regular enum in typescript, except that the compiled code does not have it, and the values inline, more details here

I apologize for not describing why a new enum generation mode is needed.

In the modern frontend, typescript is used exclusively as a type checking system.
That's why all the things that are not in pure JS: enum, private class method, namespace try not to use.

In TypeScript 3.4 const assertions were added - and this allowed to abandon enum in favor of plain js object, without loss of typing

The main difference between (enum / const enum) and typed object (as const) is that in the code we can pass enum values of type as a string, here is an example

enum MyEnum {
  A_B_C = 'A_B_C',
}

export const MyEnumConst = {
  ABC: 'A_B_C',
} as const;
export type MyEnumConst = typeof MyEnumConst[keyof typeof MyEnumConst];


const a: MyEnum = 'A_B_C'; // ERROR
const b: MyEnumConst = 'A_B_C'; 

enumAsConst equals enumsAsTypes, but add enum-like object, in output

// enumsAsTypes
export type MyEnum = 'A' | 'B';
// we not can use MyEnum.A

// enumAsConst
export const MyEnumConst = {
  A: 'A',
} as const;
export type MyEnumConst = typeof MyEnumConst[keyof typeof MyEnumConst];

// MyEnum === MyEnumConst
// but we can use MyEnumConst.A

@dotansimha
Copy link
Owner

Got it!
Thank you @DragorWW :)

@dotansimha dotansimha merged commit 700f32f into dotansimha:master Mar 8, 2020
@DragorWW DragorWW deleted the const branch March 10, 2020 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants