38668


TypeScript 2.5.3 において、コンパイルオプション **strict** で以下のコードをトランスパイルすると、エラーが出ます。

[code]

    enum Animal {
        Cat = 'ねこ',
        Dog = 'いぬ'
    }
    const key = Animal['ねこ'];
    
[/code]

> error TS7015: Element implicitly has an 'any' type because index expression
> is not of type 'number'.

enum の中身が数値のときは、上のエラーを出さずに値からキーの文字列を取り出すことができます。  
`--strict` オプションを付けたまま、文字列値の enum に対してキーを逆引きすることは可能でしょうか？


CC BY-SA 3.0
2017-10-13T05:09:23.467
38667
2017-10-13T05:09:23.467
19110
question
typescript
string enum で値からキーを取得したい


値からキーを逆引きできる機能は reverse mapping と呼ばれていますが、TypeScrip 2.5 現在、この機能はメンバーが number
型である enum で使うことが想定されています。特に、string 型のメンバに対しては実装されていません。実際 TypeScript
の[ドキュメント](https://www.typescriptlang.org/docs/handbook/enums.html)にも

> Keep in mind that string enum members do not get a reverse mapping generated
> at all.

と書かれています。これは実装上 enum のキーは string であり、キーと値の型が同じだと面倒だからです
(たとえば文字列として同一なキーと値があるときに困ります)。このことは一般の型に対する enum を導入した[この
issue](https://github.com/Microsoft/TypeScript/issues/1206#issuecomment-243622789)
でも議論されています。

* * *

ですが、型の恩恵を無視してしまうなら、any 型にキャストしてしまうことでコンパイルを通し、reverse mapping
相当の動作をさせることはできます。この場合、変なことになっていないかは自分で確認する必要があります。

[code]

    // dirty hack
    enum Animal {
        Cat = <any>'ねこ',
        Dog = <any>'いぬ'
    }
    const key = Animal[<any>'ねこ']  // ==> 'Cat'
    
[/code]

あるいは、以下のように自前の関数として実装してしまう方法があります。これは手間ですが any 型を使うことはなくなります。

[code]

    enum Animal {
        Cat = 'ねこ',
        Dog = 'いぬ'
    }
    
    function animal(key: string): string | undefined {
        switch (key) {
        case 'ねこ':
          return 'Cat'
        case 'いぬ':
          return 'Dog'
        default:
          return undefined;
        }
    }
    
    const key = animal('ねこ');
    
[/code]

また、本家 Stack Overflow の ["Reverse-Mapping for String
Enums"](https://stackoverflow.com/q/44883072/5989200) という質問も参考になるかもしれません。


CC BY-SA 3.0
2017-10-13T05:09:23.467
38668
2017-10-13T05:09:23.467
19110
38667
answer