TypeScript: ประเภทผลลัพธ์มีทุกคีย์ที่ระบุไว้เป็นพารามิเตอร์
ฉันต้องการเขียนฟังก์ชันในลักษณะที่ ประเภทค่าที่ส่งกลับจะเป็นอ็อบเจ็กต์ ซึ่งมีคีย์ตรงตามที่ระบุในอาร์เรย์เป็นพารามิเตอร์ทั้งหมด นอกจากนี้คีย์เหล่านี้ทั้งหมดควรเป็นประเภท enum ที่กำหนด ฉันได้ลองทำหลายวิธีแล้ว แต่ไม่สามารถทำให้มันทำงานได้ บางทีใครบางคนอาจจะรู้ว่ามันเป็นไปได้หรือไม่ และจะทำอย่างไร
enum Status {
TIME = 'time',
LOCATION = 'location'
}
function getStatus(statusToGet: Status[]) {
// This function will always return an object containing all passed in
// status as a key and boolean as a value, e.g.
return statusToGet.reduce((prev, stat) => {
prev[stat] = true; // or false
return prev;
}, {});
}
getStatus([]) // -> {}
getStatus([Status.TIME]) // -> { time: true }
getStatus([Status.TIME, Status.LOCATION]) // -> { time: true, location: false }
เป็นไปได้ไหมที่จะพิมพ์ฟังก์ชัน getStatus ให้ถูกต้อง เพื่อให้ TS รู้ว่าคีย์ใดอยู่ในชนิดของค่าที่ส่งกลับ
คำตอบ #1
คุณสามารถใช้ประเภทที่แมปเพื่อแมปอาร์เรย์ของประเภทสตริงลิเทอรัลไปยังวัตถุได้:
enum Status {
TIME = 'time',
LOCATION = 'location'
}
function getStatus<T extends Status>(statusToGet: T[]): { [P in T]: boolean } {
return null as any;
}
getStatus([]) // -> {}
getStatus([Status.TIME]) // -> { time: true }
getStatus([Status.TIME, Status.LOCATION]) // -> { time: true, location: false }
หมายเหตุ โค้ดข้างต้นจะคืนค่า { [s:string] :any} สำหรับอาร์เรย์ว่าง ถ้าไม่ได้เปิดใช้การตรวจสอบ null อย่างเข้มงวด สิ่งนี้เกิดขึ้นเพราะ T จะถูกสรุปเป็น any เพื่อแก้ไขปัญหานี้ เราสามารถใช้ประเภทตามเงื่อนไขเพื่อตรวจสอบว่า T เป็น any หรือไม่ และคืนค่า {} อย่างชัดเจน (ขอบคุณ @jcalz สำหรับการทดสอบ any จากคำตอบนี้) ซึ่งหมายความว่าอาร์เรย์ใด ๆ ของ any จะสร้าง {} แต่เนื่องจากเราคาดว่าเป็นอาร์เรย์ของค่าของ enum ไม่ใช่อาร์เรย์ของ any สิ่งนี้อาจไม่เป็นปัญหามากนัก อาจจะเป็นฟีเจอร์เลยด้วยซ้ำ
function getStatus<T extends Status>(statusToGet: T[]): true extends false & T? {} : { [P in T]: boolean } {
return null as any;
}
