Swagger-codegen: [TypeScript] String enums allow incorrect widening

Created on 21 Mar 2017  路  4Comments  路  Source: swagger-api/swagger-codegen

Description

swagger-codegen emits TypeScript enums in the form of:

export namespace Foo {
  export enum Bar {
    baz = <any> "baz",
    spam = <any> "spam"
  }
}

This is a hack to support string-based enums, since TypeScript's built-in support for enums only support numbers. However, this workaround is extremely dangerous, since it allows incorrectly widening the enum value to the number type even though it is a string:

const x: number = Foo.Bar.baz; // this compiles, even though it shouldn't
const y: string = Foo.Bar.baz; // this does not compile, even though it should
Swagger-codegen version

As late as 55443da

Swagger declaration file content or url

Any declaration file containing a string enum

Command line used for generation

Any swagger-codegen invocation that generates TypeScript

Suggest a Fix

According to a TypeScript dev, since TS 2.1, you can safely write string-based enums without the builtin enum keyword. This approach has minimal overhead and exploits keyof, lookup types, and type inference.

TypeScript Enum Discussion

Most helpful comment

With TypeScript 2.4, you should not need the <any> casts when writing a string enum. This gives you the correctly emitted object without duplicates.

All 4 comments

typescript 2.4 will support string enums: https://github.com/Microsoft/TypeScript/pull/15486

Why the typescript enum type generate with <any> which make it duplicate

export enum xxxTypeEnum {
        AAA = <any> 'AAA',
        BBBB = <any> 'BB_BB',
        CCC = <any> 'CCC'
    }

And when I use for (let obj in xxxTypeEnum), there will be 4 items, and the BBBB will be duplicated with BBBB and BB_BB.

Is there any reason to add this generic?
See this demo

With TypeScript 2.4, you should not need the <any> casts when writing a string enum. This gives you the correctly emitted object without duplicates.

Any update on this topic? Removing <any> from enum values generated by codegen would be very helpful. So far I have manually removed unnecessary <any> casts every time we regenerate code using codegen to keep TypeScript type checks working correctly. It would be nice to not have to change this manually.

Was this page helpful?
0 / 5 - 0 ratings