استخراج المفاتيح من كائن في TypeScript حيث يحتوي كل قيمة مفتاح على خاصية محددة
لدي كائن للقراءة فقط يُستخدم لتمثيل الإحصائيات للعبتي كما يلي:
const STATS = {
gp: {
name: "Games Played",
slug: "GP",
},
minp: {
name: "Minutes Played",
slug: "MINP",
},
minpg: {
name: "Average Minutes Per Game",
slug: "MINPG",
generated: {
// ...properties,
},
},
avgrec: {
name: "Average Receptions",
slug: "avgrec",
generated: {
// ...properties,
},
},
} as const;
أريد استخراج كل المفاتيح من الكائن التي تحتوي على خاصية generated مضبوطة. بهذه الطريقة يمكنني استخدام هذا المفتاح في بعض من دوال المساعدة الخاصة بي. لذلك، جربت ما يلي:
type GeneratedStatKeys = {
[I in keyof typeof STATS]: typeof STATS[I]["generated"] extends undefined
? never
: typeof STATS[I];
}; // "minpg" | "avgrec"
يجب أن يكون GeneratedStatKeys نوع اتحاد من السلاسل، المفاتيح المستخرجة من STATS. ومع ذلك، يقوم Typescript بإظهار خطأ "لا يمكن استخدام النوع 'generated' كمفتاح لفهرسة النوع STATS"
هذا منطقي، لذلك قمت بتوضيح كائن STATS ليكون:
const STATS: Record<string, Stat> = {
//...stats
} as const;
حيث Stat هو:
interface Stat {
name: string;
slug: string;
generated?: {
//...props
};
}
هذا يعمل، ومع ذلك، نوع GeneratedStatKeys يصبح بعد ذلك سلسلة.
ما هو الحل البديل؟ يمكنني فقط إنشاء نوع اتحاد سلسلة للمفاتيح المولدة يدويًا، لكن كنت أتساءل عما إذا كان يمكن "أتمتته".
الإجابة رقم 1
لا يمكنك الوصول إلى نوع باستخدام مفتاح إلا إذا كان مفتاحًا معروفًا من النوع. نظرًا لأن بعض الخصائص في typeof STATS لا تحتوي على مفتاح generated، لا يمكنك الوصول إلى خاصية عشوائية بهذه الطريقة. بدلاً من ذلك، يمكنك التحقق مما إذا كانت الخاصية تحتوي على هذا المفتاح باستخدام عامل التشغيل keyof:
type GeneratedStatKeys = {
[K in keyof typeof STATS]: "generated" extends keyof typeof STATS[K] ? K : never
}[keyof typeof STATS]
// type GeneratedStatKeys = "avgrec" | "minpg"
بمجرد أن تقوم بهذا الفحص، يمكنك القيام بالوصول المفهرس (على سبيل المثال، "generated" extends keyof Foo ? Foo[K] : ...) ولكن في حالتك أنت تريد المفتاح فقط، وليس نوع الخاصية.
رابط الملعب إلى الكود
