typescript - ดึงประเภทของคุณสมบัติจาก oneof
ฉันมีประเภท A ดังนี้:
type OneOf =
| {
$case: 'one';
one: One;
}
| {
$case: 'two';
two: Two;
}
| {
$case: 'three';
three: Three;
};
ฉันต้องการสร้างประเภทใหม่เพื่อให้สามารถรับจากอินพุต OneOf และรับผลลัพธ์เป็น One | Two | Three ได้
ฉันได้ลองหลายวิธีต่าง ๆ รวมถึงวิธีหนึ่งจากคำตอบนี้ที่มี UnionToIntersection ด้วยความหวังว่าด้วยการหาภาพตัดกัน ฉันจะสามารถยกเว้น $case ได้ง่าย ๆ ลูปผ่านคีย์และส่งคืนชนิดข้อมูล
ฉันมักจะได้ประเภท never เป็นผลลัพธ์เสมอ
โดยพื้นฐานแล้ว ฉันคิดว่าฉันสามารถหลีกเลี่ยงได้ด้วยสิ่งต่อไปนี้:
type ExtractOneOfTypes<T, K extends keyof T = keyof T> = {
[key in K]: T extends { $case: key } ? T[key] : never;
}[K];
เพราะใน oneOf ของฉัน สำหรับแต่ละ $case บนวัตถุเดียวกันนั้นมีชื่อคุณสมบัติที่ตรงกับค่าของ $case แต่สิ่งนี้ใช้ไม่ได้ มีไอเดียไหม?
คำตอบ #1
คุณสามารถ อนุมาน ประเภทค่าตัวอักษรของ $case แล้วตรวจสอบว่ามันเป็น keyof T หรือไม่ โดยใช้ประเภทเชิงเงื่อนไขซ้อนกันดังนี้:
type One = { one: string };
type Two = { two: number };
type Three = { three: boolean };
type OneOf =
| { $case: "one"; one: One }
| { $case: "two"; two: Two }
| { $case: "three"; three: Three };
type ExtractOneOfTypes<T, K extends keyof T> = T extends { [Key in K]: infer U }
? U extends keyof T
? T[U]
: never
: never;
type ExtractedType = ExtractOneOfTypes<OneOf, "$case">;
// ^? type ExtractedType = One | Two | Three
สนามเด็กเล่น TypeScript
