microsoft / microsoft/TypeScript
Suggesion: Allow recursive/self-references in `satisfies` constraint
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Go
- Star
- 111k
- Fork
- 14.4k
- Merge trung bình
- 1 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 117
Mô tả
Suggestion
🔍 Search Terms
satisfies keyword, recursion, recursive, constraint, self referential
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
It would only make previously rejected type assertions possible as it only widens the set of valid type restrictions.
- This wouldn't change the runtime behavior of existing JavaScript code
satisfiesonly exists during type checking and does not in generated JavaScript - This could be implemented without emitting different JS based on the types of the expressions
As above
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
As above
- This feature would agree with the rest of TypeScript's Design Goals.
The same is already possible using a constrained identity function
⭐ Suggestion
It is currently not possible to reference the type of a variable that the satisfies constraint is applied on. Enabling this functionality should not be hard, as the same behavior can be recreated using a constrained identity function, see below. This would enable more precise verification of structures by the type checker.
📃 Motivating Example
// I define a (very simplified) state machine by the following type:
type States<S extends string> = Record<S, S>;
// I can then define a map of machine names to their states records:
const myMachines1 = {
alan: {
a: "b",
b: "c",
c: "c",
},
turing: {
x: "y",
y: "x",
},
} satisfies Record<string, States<string>>;
// Problem: This is possible, though should be invalid:
const myMachines2 = {
foo: {
a: "x",
},
bar: {
x: "a",
}
} satisfies Record<string, States<string>>;
// Solution 1: Identity function with self-referential generic:
function defineMachines<T extends {
[name in keyof T]: States<keyof T[name] & string>;
}>(machines: T) {
return machines;
}
// Valid:
const myMachines3 = defineMachines({
alan: {
a: "b",
b: "c",
c: "c",
},
turing: {
x: "y",
y: "x",
},
});
// Errors:
const myMachines4 = defineMachines({
foo: {
a: "x",
},
bar: {
x: "a",
}
});
// Solution 2: The same behavior should be achievable using the new `satisfies` keyword:
const myMachines5 = {
foo: {
a: "x",
},
bar: {
x: "a",
}
} satisfies {
[name in keyof typeof myMachines5]: States<keyof typeof myMachines5[name] & string>;
};
// But errors: Block-scoped variable 'myMachines5' used before its declaration.
💻 Use Cases
As seen in the example above, this allows for a more precise control over (nested) type restrictions. It is already possible to self-reference type definitions, so why shouldn't this also be possible for variable declarations? The satisfies keyword does not modify the type itself to my knowledge.
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- 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ụ tạo động lực cho satisfies và so sánh tham chiếu chính nó bị từ chối với giải pháp hàm đồng nhất có ràng buộc. Xác định các ràng buộc đệ quy nên hoạt động như thế nào đối với các khai báo biến, sau đó xác thực rằng các map máy trạng thái hợp lệ được chấp nhận và các tham chiếu chéo không hợp lệ bị từ chối mà không thay đổi đầu ra khi chạy.
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
- 30/100