Làm thế nào để định nghĩa một kiểu chuỗi phù hợp với regex trong Typescript?
Có thể định nghĩa một giao diện mà có một số thông tin về định dạng của một chuỗi không? Hãy xem ví dụ sau:
interface timeMarkers{
markerTime: string[]
};
một ví dụ sẽ là:
{
markerTime: ["0:00","1:30", "1:48"]
}
Câu hỏi của tôi: Có cách nào để xác định kiểu cho markerTime sao cho giá trị chuỗi luôn phải khớp với biểu thức chính quy này, thay vì chỉ khai báo nó là string[] và thực hiện từ đó không?
var reg = /[0-9]?[0-9]:[0-9][0-9]/;Câu trả lời #1
Không có cách nào để định nghĩa một loại như vậy. Có một đề xuất trên GitHub để hỗ trợ điều này, nhưng hiện tại có vẻ nó không phải là ưu tiên. Hãy bỏ phiếu cho nó và có thể nhóm sẽ đưa nó vào một phiên bản phát hành trong tương lai.
Chỉnh sửa
Bắt đầu từ phiên bản 4.1, bạn có thể định nghĩa một kiểu template literal mà sẽ xác thực chuỗi mà không cần thực sự định nghĩa tất cả các tùy chọn:
type MarkerTime =`${number| ''}${number}:${number}${number}`
let a: MarkerTime = "0-00" // error
let b: MarkerTime = "0:00" // ok
let c: MarkerTime = "09:00" // ok
Liên kết Sân chơi
Câu trả lời số 2
Cho đến khi các loại regex trở nên có sẵn trong ngôn ngữ, bạn hiện có thể sử dụng các loại template literal trong TS 4.1.
Hãy để tôi tham khảo ví dụ câu hỏi và minh họa cách mô hình hóa một kiểu string có giới hạn về thời gian gọi là Time. Time yêu cầu các chuỗi ở định dạng hh:mm (ví dụ "23:59") ở đây để đơn giản hóa.
Bước 1: định nghĩa các kiểu HH và MM
Array.from({length:24},(v,i)=> i).reduce((acc,cur)=> `${acc}${cur === 0 ? "" : "|"}'${String(cur).padStart(2, 0)}'`, "type HH = ")
Array.from({length:60},(v,i)=> i).reduce((acc,cur)=> `${acc}${cur === 0 ? "" : "|"}'${String(cur).padStart(2, 0)}'`, "type MM = ")
type HH = '00'|'01'|'02'|'03'|'04'|'05'|'06'|'07'|...|'22'|'23'
type MM = '00'|'01'|'02'|'03'|'04'|'05'|'06'|'07'|...|'58'|'59'
Bước 2: Khai báo Time
type Time = `${HH}:${MM}`
Đơn giản như vậy.
Bước 3: Một số thử nghiệm
const validTimes: Time[] = ["00:00","01:30", "23:59", "16:30"]
const invalidTimes: Time[] = ["30:00", "23:60", "0:61"] // all emit error
Đây là một ví dụ mã trực tiếp để thử nghiệm với Time.
Câu trả lời #3
type D1 = 0|1;
type D3 = D1|2|3;
type D5 = D3|4|5;
type D9 = D5|6|7|8|9;
type Hours = `${D9}` | `${D1}${D9}` | `2${D3}`;
type Minutes = `${D5}${D9}`;
type Time = `${Hours}:${Minutes}`;
Giải pháp gọn gàng tổng hợp các ý tưởng từ @bela53 và @yoel halb.
Giải pháp này có 2039 thành viên enum cho kiểu Time.
Sân chơi Ts
Câu trả lời #4
Dựa trên câu trả lời của @bela53 nhưng đơn giản hơn nhiều, chúng ta có thể thực hiện một giải pháp rất đơn giản tương tự như của @Titian nhưng không có nhược điểm:
type HourPrefix = '0'|'1'|'2';
type MinutePrefix = HourPrefix | '3'|'4'|'5';
type Digit = MinutePrefix |'6'|'7'|'8'|'9';
type Time = `${HourPrefix | ''}${Digit}:${MinutePrefix}${Digit}`
const validTimes: Time[] = ["00:00","01:30", "23:59", "16:30"]
const invalidTimes: Time[] = ["30:00", "23:60", "0:61"] // all emit error
