microsoft / microsoft/TypeScript

Allow importing both type entity and value entity for "const enum" through "import type"

Đang mở
#40,344 17 bình luận 21 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Awaiting More Feedback Suggestion
Ngôn ngữ chính
Go
Star
111k
Fork
14.3k
Merge trung bình
2 ngày 4 giờ
Pull request đã merge (30 ngày)
132

Mô tả

Search Terms

const enum, import, importsNotUsedAsValues

Scenario

I am a library developer, and there is a really large types.ts file in my project, which contains many interface, type, and const enum, defining a large part of types of the project, just like you do (typescript/src/compiler/types.ts).

Recently I turned on the compiler option importsNotUsedAsValues, and found some problems about const enum.

Original fileA.ts

import {
    TypeA, TypeB, TypeC,
    ConstEnumD, ConstEnumE,
} from './types.ts';

------------------

Current fileA.ts

import type {
    TypeA, TypeB, TypeC,
} from './types.ts';
import {
    ConstEnumD, ConstEnumE,
} from './types.ts';

Because the entities of enum belong to both type scope and value scope, I have to import them separately if I want to use them as values.

Now I have to separate the import of type const enum from a lot of names file by file, which is really a lot of work.

What's worse, after turning on importsNotUsedAsValues, TypeSciprt unnecessarily write require('./types.js') into fileA.js though the generated code did not access any property of require('./types.js'). In other words, it makes types.ts seems to have side effects. And this feature may affect the file reference relation of the project and lead to incorrect Rollup order.

In my mind, accessing the const enum entity in value scope is a kind of special behavior and is something that will be replaced in compile-time. There should be a way to import both type entity and value entity of const enum from a file without really requiring the file, especially when the file really has side effects.

Solution

There are 2 ways to solve this problem:

1. import both type and value for const enum through import type
import type { ConstEnumA } from './types';
//       Type↓        Value↓
const a: ConstEnumA = ConstEnumA.propA;

// ts not emit "  require('./types')  "

I prefer this method because I will not need to greatly change my code.

Breaking change?

Name conflicts may occur if there was already a name in value scope which was same with 'ConstEnumA',
but I think this is very very rare and will be prevented by linter usually. An extra compiler option can be provided to solve this.

2. check const enum in value-import
// importsNotUsedAsValues is still on

import { ConstEnumA } from './types';
//       Type↓        Value↓
const a: ConstEnumA = ConstEnumA.propA;

// ts find just "ConstEnumA" is used and it is `const enum`
// not emit "  require('./types')  "
Breaking change?

Yes. Now TS do not emit require('...') though value-import exists in the code.

Examples

A complete example of Solution 1:

import type {
    TypeA,
    TypeB,
    TypeC,
    ConstEnumA,
    TypeD,
    TypeE,
    TypeF,
    ConstEnumB,
    TypeG,
    TypeH,
    TypeI,
    ConstEnumC,
    ConstEnumD,
    TypeJ,
    TypeK,
} from './types';

const b: ConstEnumB = ConstEnumB.propA;
// compiler: OK, 0 error(s). not emit "  require('./types.js')  "

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với các ví dụ fileA.tstypes.ts trong issue cũng như hành vi của importsNotUsedAsValues được mô tả ở đó. So sánh hai giải pháp được đề xuất, sau đó xác minh rằng thiết kế được chọn cho phép sử dụng const enum dưới dạng kiểu và giá trị thông qua import type mà không phát sinh require('./types.js'), đồng thời vẫn giữ nguyên hành vi JavaScript hiện có.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
typescript
Lĩnh vực
compilers
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.