microsoft / microsoft/TypeScript

Support some non-structural (nominal) type matching

Đang mở
#202 498 bình luận 1087 reaction 0 người được giao Xem trên GitHub

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

In Discussion Suggestion
Ngôn ngữ chính
Go
Star
111k
Fork
14.3k
Merge trung bình
1 ngày 19 giờ
Pull request đã merge (30 ngày)
117

Mô tả

Proposal: support non-structural typing (e.g. new user-defined base-types, or some form of basic nominal typing). This allows programmer to have more refined types supporting frequently used idioms such as:

  1. Indexes that come from different tables. Because all indexes are strings (or numbers), it's easy to use the an index variable (intended for one table) with another index variable intended for a different table. Because indexes are the same type, no error is given. If we have abstract index classes this would be fixed.

  2. Certain classes of functions (e.g. callbacks) can be important to be distinguished even though they have the same type. e.g. "() => void" often captures a side-effect producing function. Sometimes you want to control which ones are put into an event handler. Currently there's no way to type-check them.

  3. Consider having 2 different interfaces that have different optional parameters but the same required one. In typescript you will not get a compiler error when you provide one but need the other. Sometimes this is ok, but very often this is very not ok and you would love to have a compiler error rather than be confused at run-time.

Proposal (with all type-Error-lines removed!):

// Define FooTable and FooIndex
nominal FooIndex = string;  // Proposed new kind of nominal declaration.
interface FooTable {
  [i: FooIndex]: { foo: number };
}
let s1: FooIndex;
let t1: FooTable;

// Define BarTable and BarIndex
nominal BarIndex = string; // Proposed new kind of nominal declaration.
interface BarTable {
  [i: BarIndex]: { bar: string };
}
let s2: BarIndex;
let t2: BarTable;

// For assignment from base-types and basic structures: no type-overloading is needed.
s1 = 'foo1';
t1 = {};
t1[s1] = { foo: 1 };

s2 = 'bar1';
t2 = { 'bar1': { bar: 'barbar' }};

console.log(s2 = s1); // Proposed to be type error.
console.log(s2 == s1); // Proposed to be type error.
console.log(s2 === s1); // Proposed to be type error.

t1[s2].foo = 100; // Gives a runtime error. Proposed to be type error.
t1[s1].foo = 100;

function BadFooTest(t: FooTable) {
  if (s2 in t) {  // Proposed to be type error.
    console.log('cool');
    console.log(t[s2].foo); // Proposed to be type error.
  }
}

function GoodBarTest(t: BarTable) {
  if (s2 in t) {
    console.log('cool');
    console.log(t[s2].bar);
  }
}

BadFooTest(t1); // Gives runtime error;
BadFooTest(t2); // No runtime error, Proposed to be type error.
GoodBarTest(t1); // Gives runtime error; Proposed to be type error.
GoodBarTest(t2);

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

Không có tệp, bài kiểm thử hoặc entry point nào được nêu tên. Hãy bắt đầu bằng cách xem xét các khai báo nominal được đề xuất cùng các trường hợp sử dụng index, callback và interface; để được xem là hoàn thành sẽ cần có một thiết kế đã được thống nhất và hành vi kiểm tra kiểu đối với các phép gán và lời gọi không hợp lệ được liệt kê.

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
Sôi nổi
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
20/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.