TypeScript - آیا میتوانم از نام ویژگی یک شیء بهعنوان مقدار رشتهای در همان شیء استفاده کنم؟


آیا میتوانم نام ویژگی یک شی را بهعنوان مقدار رشتهای در همان شی استفاده کنم؟ منظورم این است که میخواهم این را بهدست آورم:

type MyObjectType = /* ... */

const myValidObject: MyObjectType = {
  a: 'a',
  b: 'b'
} // valid object of type MyObjectType

const myInvalidObject: MyObjectType = {
  a: 'a',
  b: 'c'
} // invalid object of type MyObjectType, property b should have value 'b'

من چیزی شبیه به این را امتحان کردهام اما جواب نمیدهد:

type MyObjectType = {
  [K: string]: `${K}`
}

پاسخ شماره ۱

هیچ نوع خاص MyObjectType در تایپاسکریپت وجود ندارد که نیازهای شما را برآورده کند. در عوض، شما میتوانید یک نوع جنریک ایجاد کنید که پارامتر نوع K اتحاد کلیدهای موجود در شیء باشد:

type MyObjectType<K extends PropertyKey> =
  { [P in K]: P }

اما شما احتمالاً نمیخواهید خودتان MyObjectType<"a" | "b"> را بنویسید. این بدان معناست که شما یک تابع کمکی جنریک میخواهید تا نوع آرگومان را برای شما استنتاج کند:

const myObjectType =
  <K extends PropertyKey>(o: MyObjectType<K>) => o;

حال به جای const o: MyObjectType={⋯}، شما مینویسید const o=myObjectType({⋯}). این تقریباً همان مقدار کار برای شما است، اما رفتار مورد نظر را به شما میدهد:

const myValidObject = myObjectType({
  a: 'a',
  b: 'b'
});
// const myValidObject: MyObjectType<"a" | "b">

const myInvalidObject = myObjectType({
  a: 'a',
  b: 'c' // error
  // Type '"c"' is not assignable to type '"b"'.
});
// const myInvalidObject: MyObjectType<"a" | "b">

لینک زمین بازی به کد