ค้นหาเว็บไซต์

อีนัมของ Typescript และโมดูลภายนอก (browserify)


จนถึงตอนนี้ฉันใช้โมดูลภายในของ TypeScript และรวมแท็กสคริปต์หลายสิบแท็กเพื่อบูตแอปของฉัน ปัจจุบันฉันอยู่ในกระบวนการแปลงโปรเจกต์ให้ใช้โมดูลภายนอก (โดยใช้ browserify) แต่ฉันติดอยู่ที่ว่าควรจะแปลง enums อย่างไร

ฉันเคยมีบางสิ่งประมาณนี้:

mymodule.submodule {
     enum MyEnum {
        one,
        two,
        three
     }
}

และฉันจะใช้มันในโมดูลอื่น ๆ ดังนี้:

var val:mymodule.submodule.MyEnum = mymodule.submodule.MyEnum.one;

และนี่ถูกคอมไพล์เป็น js อย่างถูกต้อง หลังจากแปลงโปรเจกต์ให้ใช้โมดูลภายนอก ผมได้ย้ายอินเทอร์เฟซทั้งหมดไปยังไฟล์ *.d.ts และคิดที่จะวาง enums ไว้ที่นั่นด้วย แต่แน่นอนว่านี่ทำให้เกิดข้อผิดพลาดเนื่องจากไม่มีการแมประหว่าง enum กับตัวเลขใน js จากนั้นผมจึงย้าย enums ไปที่ไฟล์ *.ts เพื่อให้พวกมันถูกคอมไพล์ ปัญหาคือถ้าผมเขียนพวกมันเป็น:

export enum MyEnum{
    one,
    two,
    three
}

export enum OtherEnum {
    four,
    five,
    six
}

ซึ่งใช้สำหรับต้องการ enums ในโค้ดของฉันดังนี้:

import Enums = require('./enums');
var val = Enums.MyEnum.one; //this works
var val1: mymodule.submodule.MyEnum = Enums.MyEnum.one; //ERROR: incompatible types

แต่ไม่สามารถใช้ร่วมกับชนิด mymodule.submodule.MyEnum ได้ แล้วฉันจะมีทั้งการประกาศสำหรับชนิด enum เพื่อให้สามารถประกาศชนิดตัวแปรภายในไฟล์ d.ts ได้อย่างไร แต่ก็ยังมีโค้ด enum ที่สร้างขึ้นจริงที่ต้องพึ่งพา (เพื่อให้มันถูกโหลดอย่างถูกต้อง) และใช้งานในไฟล์ .ts ได้?

หมายเหตุ: อีนัมเหล่านี้ถูกใช้ในหลายโมดูล ดังนั้นการรวมมันไว้ในไฟล์เดียวกับที่ใช้งานจึงไม่ใช่ทางแก้ไข

อัปเดต เกี่ยวกับการประกาศอินเทอร์เฟซ: อาจจะยังไม่ชัดเจนว่าทำไมฉันถึงเก็บการประกาศ enum ดั้งเดิมในไฟล์ d.ts ดังนั้นฉันจึงกำลังเพิ่มตัวอย่าง

ในไฟล์ interfaces.d.ts ตอนนี้ฉันมี:

declare module mymodule.submodule {
    enum MyEnum{
       one,
       two,
       three
    }

    interface ISomething{
       aValue: MyEnum;
       aFunction: (anArg: MyEnum) => void;
    }
}

เท่าที่ฉันรู้ ฉันไม่สามารถใช้คำสั่ง import ในไฟล์ .d.ts ได้ ดังนั้นฉันจะใช้ประกาศ enum หนึ่งรายการในทุกกรณีได้อย่างไร?

คำตอบ #1

enum จำเป็นต้องอยู่ในไฟล์ TS เพราะ enum จะถูกคอมไพล์เป็น JavaScript เมื่อใช้โมดูล enum จำเป็นต้องถูกนำเข้าเพื่อใช้งาน (แม้กระทั่งเมื่อใช้เพียงเพื่อกำหนดประเภทของตัวแปร)

เปลี่ยนโค้ดเป็นดังต่อไปนี้:

import Enums = require('./enums');
var val1: Enums.MyEnum = Enums.MyEnum.one; // no error

นอกจากนี้ enums ไม่ควรอยู่ใน mymodule.submodule หากมันถูกกำหนดใน enums.ts ให้ลบมันออกจากไฟล์การกำหนด

เกี่ยวกับการอัปเดต

เพื่อให้ enums ทำงานกับ interfaces ได้ คุณสามารถย้าย interfaces ออกมาจากไฟล์ประกาศ (interfaces.d.ts) และส่งออกจากไฟล์ typescript (เช่น interfaces.ts):

import Enums = require('./enums');

export interface ISomething {
   aValue: Enums.MyEnum;
   aFunction: (anArg: Enums.MyEnum) => void;
}

จากนั้นคุณสามารถใช้ส่วนติดต่อแบบนี้:

import Interfaces = require('./interfaces');
import Enums = require('./enums');

var example: Interfaces.ISomething = {
    aValue: Enums.MyEnum.one,
    aFunction: (example: Enums.MyEnum) => { console.log('example'); }
};

บทความที่เกี่ยวข้อง