microsoft / microsoft/TypeScript

Pipe Operator instead of conditions and deep extends

Đang mở
#61,819 4 bình luận 0 reaction 0 người được giao Xem trên GitHub
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

- switch case
- switch case type level
- pipe operator ts
- pipe operator typescript
- avoid nested extends
- pipe ts type level
- type level switch
- switch typescript

### ✅ Viability Checklist

- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ Suggestion

My suggestion is to add a kind of idiomatic switch case for typescript types, where we could verify a list of `extends` without nesting.

**ERRATUM:** It does more than just adding syntax sugar to syntax, and behaves differently to a switch case. In this case, it determines a set of conditions that computes and returns the first found matching conditions. This way we could have more complex checking, instead of a simple "If Type T matches other Type U".

The example below does this. It not only checks "equality" and also does more things like calling other utility changes and then doing a condition check.

So, instead of a "switch case", it would likely feel closer to a syntax sugar to a sequence of "ifs".

Imagine a "replace" function that takes a text, find placeholders and provide an object with that placeholders as keys. This is how it can be achieved now:

```typescript
type Whitespace = '\n' | '\t' | ' ';

type TrimLeft =
T extends `${Whitespace}${infer S extends string}` ? TrimLeft : T;
type TrimRight =
T extends `${infer S extends string}${Whitespace}` ? TrimRight : T;
type Trim = TrimRight>;

type Equal = [A] extends [B] ? ([B] extends [A] ? true : false) : false;

type IsJustString = Equal;

type Placeholders =
IsJustString extends true
? string
: Equal extends true
? Result
: T extends `${string}{{${infer P extends string}}}${infer Rest extends string}`
? Placeholders>
: Result;

export function withText(text: T) {
return {
replace: (contents: Record, string>) => {
let result: string = text;
for (const [key, value] of Object.entries(contents)) {
result = result.replace(`{{${key}}}`, value as string);
}
return result;
},
};
}

const helloWorld = withText("{{greeting}}, {{person}}").replace({
greeting: "Hello",
person: "World"
})
```

This is how it would look on my proposal:

```
type Whitespace = '\n' | '\t' | ' ';

type TrimLeft =
|> T extends `${Whitespace}${infer S extends string}`: TrimLeft,
|> T;
type TrimRight =
|> T extends `${infer S extends string}${Whitespace}`: TrimRight,
|> T;
type Trim = TrimRight>;

type Equal = [A] extends [B] ? ([B] extends [A] ? true : false) : false;

type IsJustString = Equal;

type Placeholders =
|> IsJustString extends true: string,
|> Equal extends true: Result,
|> T extends `${string}{{${infer P extends string}}}${infer Rest extends string}`: Placeholders>,
|> Result;

export function withText(text: T) {
return {
replace: (contents: Record, string>) => {
let result: string = text;
for (const [key, value] of Object.entries(contents)) {
result = result.replace(`{{${key}}}`, value as string);
}
return result;
},
};
}

const helloWorld = withText("{{greeting}}, {{person}}").replace({
greeting: "Hello",
person: "World"
})
```

### 📃 Motivating Example

Sometimes nested extends can be too complicated to understand:

- The depth is is unmanageable
- Doesn't separate different concerns (are we still verifying possible values of T or are we doing something else?)
- Makes it hard to format
- Makes it hard to read

### 💻 Use Cases

1. What do you want to use this for?

Replace deep extends checks

2. What shortcomings exist with current approaches?

- Split into different types with different concers
- Format so that it looks like a "switch case"

3. What workarounds are you using in the meantime?

I have presented above

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

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

Hướng nghiên cứu

Issue không nêu tên các tệp trong repository, các bài kiểm thử hoặc các điểm vào. Hãy bắt đầu bằng việc xem xét cách TypeScript hiện phân tích cú pháp và đánh giá các kiểu có điều kiện, sau đó xác định cú pháp cần thiết, hành vi kiểm tra kiểu, các chẩn đoán và các bài kiểm thử tương thích. Chỉ được xem là hoàn tất khi có thiết kế được chấp thuận và kế hoạch triển khai, không chỉ là một chỉnh sửa cục bộ.

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.