เจเนอริก - วิธีเลือก property ตามเงื่อนไขถ้าเป็นส่วนของสตริงที่กำหนดใน Typescript
เป้าหมายของฉันคือการพิมพ์ฟังก์ชัน removeUrl:
type MyType = {
name: string;
last_name: string;
children_url: string;
children2_url: string;
children3_url: string;
// ...
}
function removeUrls(target: MyType): MagicType {
const result = {}
for (const key in target) {
if (!key.includes('_url')) {
result[key] = target[key]
}
}
return result;
}
นี่อาจจะเป็นคำถามง่ายๆ แต่ฉันเป็นมือใหม่ในโลกของ TypeScript Generics และหาผลลัพธ์ที่ดีใน Google เกี่ยวกับปัญหานี้ค่อนข้างยาก :/
คำตอบ #1
นี่ไม่สามารถทำได้บน TypeScript 4.0
แต่ในรุ่นเบต้า 4.1 ที่ยังไม่วางจำหน่ายผ่าน Template Literal Types คุณมีตัวเลือกบางอย่าง!
ถ้าคุณเพิ่งเริ่มใช้ TypeScript สิ่งนี้อาจดูแปลกไปบ้าง:
type UrlKeys<T> = {
[K in keyof T]: K extends `${infer Prefix}_url` ? K : never
}[keyof T]
type RemoveUrls<T> = Omit<T, UrlKeys<T>>
ประเภท UrlKeys ทำการวนซ้ำผ่านคุณสมบัติของวัตถุ สำหรับแต่ละคีย์ ถ้าคีย์ K มี Prefix บางอย่างตามด้วย _url ที่ด้านท้าย ให้คืนชื่อคีย์นั้น มิฉะนั้นให้คืนค่า never ส่วน [keyof T] ที่ท้ายสุดจะได้ยูเนียนของคีย์ทั้งหมดที่ไม่ได้ถูกกำหนดให้เป็น never
จากนั้น RemoveUrls จะรับเพียงชนิดหนึ่งและ Omit คีย์ใด ๆ ที่จะถูกพิจารณาว่าเป็น _url
คุณจะใช้ประเภทเหล่านั้นแบบนี้:
function removeUrls<T>(target: T): RemoveUrls<T> {
const result: Partial<T> = {}
for (const key in target) {
if (!key.includes('_url')) {
result[key] = target[key]
}
}
return result as T;
}
const result = removeUrls({ a: 123, b_url: 'http://example.com' }) // type: { a: number }
โปรดทราบว่าฟังก์ชันนี้ตอนนี้มีพารามิเตอร์ทั่วไป T เพื่อรับประเภทใดก็ได้ และค่าที่ส่งกลับจะเป็นประเภทเดียวกัน ยกเว้นคุณสมบัติ url
นอกจากนี้ เมื่อสร้างอ็อบเจ็กต์ทีละคุณสมบัติแบบนี้ คุณจะต้องพิมพ์อ็อบเจ็กต์ที่กำลังสร้างเป็น Partial เพื่อให้สามารถยอมรับได้ว่ามีบางคุณสมบัติที่ยังไม่ครบขณะกำลังสร้าง จากนั้นในคำสั่ง return คุณสามารถแปลงกลับเป็น T เต็มได้เนื่องจากคุณทราบว่าคุณได้ประมวลผลคุณสมบัติทั้งหมดแล้ว
สนามเด็กเล่น
