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

javascript - typescript ตรวจสอบแบบไดนามิกว่าสตริงเป็นคุณสมบัติของวัตถุซับซ้อนหรือไม่


ฉันต้องสามารถตรวจสอบแบบไดนามิกได้จริงๆ ว่า aa เป็นคุณสมบัติของวัตถุซับซ้อนของฉันที่เรียกว่า validations หรือไม่

const check = 'propertya' + 'a'; // result of a complex calculation that returns string 'propertyaa'

validations= {
    'a' : {
      'propertyaa': 'ax',
      'ab': 'ay',
      'ac': 'az'
    },
    'b' : {
      'ba': 'ax',
      'bb': 'ay',
      'bc': 'az'
    }
  };

if (this.validations.a[check] === undefined) {  ...

ข้อผิดพลาดคือ:

element implicitly has an any type because type '{ ' propertyaa': string, 'ab': string, 'ac': string; }' has no index signature
(property) 'a': {
    'propertyaa': string;
    'ab': string;
    'ac': string;
}

อย่างน่าสงสัย รุ่นคงที่ (ไม่ใช่แบบไดนามิก) ทำงาน if (this.validations.a['ab']) {

คำตอบ #1

คุณสามารถเลือกหนึ่งในสองวิธี คุณสามารถเพิ่มลายเซ็นดัชนีไปยังคุณสมบัติการตรวจสอบของคุณ:

type Indexable = { [name: string]: string }
const validations = {
    'a': {
        'propertyaa': 'ax',
        'ab': 'ay',
        'ac': 'az'
    } as Indexable,
    'b': {
        'ba': 'ax',
        'bb': 'ay',
        'bc': 'az'
    } as Indexable
};

const check = 'propertya' + 'a';
if (validations.a[check] === undefined) {
}

คุณก็สามารถแคสต์คุณสมบัตินั้นเป็น Indexable เมื่อคุณใช้งานมันได้เช่นกัน:

if ((validations.a as Indexable)[check] === undefined) {
}

คุณยังสามารถใช้ any แทน Indexable ได้เช่นกัน แต่ Indexable ที่กำหนดด้านบนจะให้ความปลอดภัยของประเภทมากกว่า any

อีกทางเลือกหนึ่งคือการยืนยันว่า สตริง check แท้จริงแล้วเป็นคีย์สำหรับค่าของ a:

if (validations.a[check as 'propertyaa'] === undefined) {
}

แก้ไข

ถ้าคุณเลือกตัวเลือกแรก ฟังก์ชันช่วยเหลือสามารถช่วยหลีกเลี่ยงความจำเป็นในการยืนยันชนิดของแต่ละคุณสมบัติของ validations:

type Indexable = { [name: string]: string }
const validations = createValidations({
    'a': {
        'propertyaa': 'ax',
        'ab': '19',
        'ac': 'az'
    },
    'b': {
        'ba': 'ax',
        'bb': 'ay',
        'bc': 'az'
    }
});
function createValidations<T>(o: { [P in keyof T]: T[P] & Indexable}) : typeof o {
    return o;
}
const check = 'propertya' + 'a';
if (validations.a[check] === undefined) {
}

คำตอบ #2

คุณจะต้องใช้ลายเซ็นดัชนี...

interface ComplexObject {
    [index: string ]: string | ComplexObject;
}

const check = 'propertya' + 'a';

const validations: ComplexObject = {
    'a' : {
      'propertyaa': 'ax',
      'ab': 'ay',
      'ac': 'az'
    },
    'b' : {
      'ba': 'ax',
      'bb': 'ay',
      'bc': 'az'
    }
  };

if (this.validations.a[check] === undefined) {
    // ...
}