ค้นหาเว็บไซต์

Tuple เป็น Object ใน TypeScript ผ่าน generics


ฉันกำลังพยายามแปลงการรวม Tuple ใน TypeScript เป็นวัตถุ โดยไม่สูญเสียประเภทใด ๆ

นี่คือตัวอย่างว่ามันจะทำงานอย่างไร:

type Tuples = ["foo", string] | ["bar", boolean] | ["baz", null];

/*
ideally the type would be:
{
  foo: string;
  bar: boolean;
  baz: null;
}
*/
type AsObject = DoSomething<Tuples>;

วิธีแก้ปัญหาอย่างง่ายต่อสิ่งที่กล่าวมาข้างต้นคือ:

type TupleToObject<T extends [string, any]> = { [key in T[0]]: T[1] };

/*
type is:
{
    foo: string | boolean | null;
    bar: string | boolean | null;
    baz: string | boolean | null;
}
*/
type TypesLost = TupleToObject<Tuples>;

อย่างไรก็ตาม เราสูญเสียข้อมูลประเภทบางอย่างไปเนื่องจากค่าทั้งหมดถูกรวมเข้าด้วยกันในประเภทยูเนียนเดียว

ฉันกำลังมองหาวิธีแก้ปัญหาโดยใช้เจเนอริกที่ไม่ทำให้ข้อมูลชนิดนี้หายไป และจะขอบคุณหากได้รับความเข้าใจเชิงลึกเกี่ยวกับการทำแผนที่ทูเพิลเจเนอริกใน TypeScript

คำตอบ #1

คุณสามารถได้รับผลลัพธ์ที่ต้องการ โดยการใช้ Extract แนวคิดพื้นฐานคือเราจะสกัดจาก T ชนิดที่เหมาะสมจากยูเนียนที่ตรงกับ key ทั่วไป:

type Tuples = ["foo", string] | ["bar", boolean] | ["baz", null];
type TupleToObject<T extends [string, any]> = { [key in T[0]]: Extract<T, [key, any]>[1] };

/*
type is:
{
    foo: string;
    bar: boolean;
    baz: null;
}
*/
type TypesLost = TupleToObject<Tuples>;

คำตอบ #2

ฉันต้องการหาวิธีแก้ปัญหาที่ง่ายขึ้นซึ่งไม่เกี่ยวข้องกับการใช้ประเภทยูทิลิตี้

คิดออกมานี่:

const tuple = [123, '321', 789, '987'] as const

type TupleToObject<T extends readonly any[]> = { [Key in T[number]]: Key }

บทความที่เกี่ยวข้อง