microsoft / microsoft/TypeScript

Proposal: allow variance annotations on input positions

Đang mở
#62,639 4 bình luận 0 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ả

⭐ Suggestion

I would like the in and out type modifiers to be able to applied to a generic type when it is being instantiated.

This would function by expanding the type by eliminating fields that are in violation of the requested constraint.

This might be thought of as another form of anonymous type mapping.

For example the code that can currently be written as

interface BivariantSetLike {
    size: number;
}
interface CovariantSetLike<out T> extends BivariantSetLike {
    getAll: () => Iterable<T>;
}
interface ContravariantSetLike<in T> extends BivariantSetLike {
    add: (key: T) => void;
}
interface SetLike<in out T>
    extends CovariantSetLike<T>,
        ContravariantSetLike<T>,
        BivariantSetLike {
    constrain: (key: T) => T | undefined
}

declare const dogs: SetLike<Dog>;
const animals: CovariantSetLike<Animal> = dogs;
const poodles: ContravariantSetLike<Poodle> = dogs;
const countable: BivariantSetLike = dogs;

Could instead be written as

interface SetLike<in out T> {
    size: number;
    getAll: () => Iterable<T>;
    add: (key: T) => void;
    constrain: (key: T) => T | undefined;
}

declare const dogs: SetLike<Dog>;
const animals: SetLike<-in Animal> = dogs;
const poodles: SetLike<-out Poodle> = dogs;
const countable: SetLike<-in -out void> = dogs;

I'm not opposed to allowing the non-negated forms to be used in type instantiations, but in line with the existing pattern that in and out already don't impose variance restrictions on otherwise variant code: I think the positive forms, if they are even syntactically allowed, should always no-op. So MyType<T> == MyType<in T> == MyType<out T> == MyType<in out T>

readonly and writeonly

field: -in T -> readonly field: T
field: -out T -> set field(value: T)
readonly field: -in T -> readonly field: T
readonly field: -out T -> (field is skipped)
set field(value: -in T) -> (field is skipped)
set field(value: -out T) -> set field(value: T)

This would break for an index signature type like {[n: number]: T} for -out T, because there is no syntax to describe a writeonly [n: number].
Perhaps, instead of simplifying types to remove the -in ReifiedT, it is just legal to use the -in and -out modifiers anywhere a type is legal inside of an object type, and it just impacts the semantics of the type.
If this were the case, it would be legal to write something like {x: -in number} as an alias for {readonly x: number}. I'm not particularly fond of this option, but it does provide an elegant answer for lacking writeonly.

Strict Methods

TypeScript treats methods and functions differently when it comes to variance (assuming --strictFunctionTypes, which is table stakes for any use of the in out modifiers anyway). I think the special treatment of methods should be ignored when using this new syntax, as it largely defeats the purpose. So WritableFunction and WritableMethod will remain distinct, but T1 and T2 ought to be be identical:

interface WritableFunction<T> {
    write: (value: T) => void;
}
interface WritableMethod<T> {
    write(value: T): void;
}

type T1 = WritableFunction<-in number>;
type T2 = WritableMethod<-in number>;

The alternative is to make a --strictMethodTypes flag that enables method type checking everywhere.
This proposal's syntax would, I believe, allow for things like Array to be mostly usable, despite their non-variance.

🔍 Search Terms

Variance covariance contravariance bivariance in out input

✅ Viability Checklist

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

Issue không nêu tên các tệp triển khai hoặc các bài kiểm thử. Hãy bắt đầu bằng cách xác định các đường dẫn kiểm tra kiểu và khởi tạo generic của TypeScript, sau đó so sánh chúng với các ví dụ về variance, readonly/writeonly, index-signature và strict-method. Công việc được xem là hoàn tất khi đã thống nhất về ngữ nghĩa của các phương án và các bài kiểm thử của trình biên dịch bao quát cú pháp được đề xuất.

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
Khá rõ ràng
Mức phù hợp với người mới
25/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.