Weboldal keresés

tömbök - A tulajdonság nem létezik ezen a típuson/nem használható index típusaként


Akarok egy objektumot, amely a gyökerében tartalmazhat sztringeket, és az arrayValues objektumban egy sztringtömböt. Ez egy konfigurációs objektum, amelyet egy alkalmazásban fognak használni.

Ez az objektum és a kulcsai dinamikusak lesznek (a felhasználói állapotértékek alapján meghatározva), így nincs módomban típusokat megadni a konkrét kulcsnév alapján.

Hozzá fogok adni tömböket az "arrayValues"-hez az alkalmazásom egy részéből, és karakterláncokat a "filters"-hez az alkalmazás egy másik részéből.

Azonban hibákat kapok az objektum tulajdonságaihoz való hozzáféréskor:
TS PLAYGROUND

export type FiltersStateType = {
  filters:
    | {
        arrayValues: { // note: this should only appear once in filters object
          [key: string]: Array<string>
        }
      }
    | { [key: string]: string }
}

const example: FiltersStateType = {
  filters: {
    arrayValues: {
      sandwiches: ['ham', 'cheese'],
      milkshakes: ['choc', 'banana'],
    },
    randomString: 'hello',
  },
}

example.filters.arrayValues.sandwiches.filter((item: string) => item !== 'ham') 
// ❌ Property 'sandwiches' does not exist on type 'string | { [key: string]: string[]; }'.
// ❌ Property 'sandwiches' does not exist on type 'string'

const stringKey = 'milkshakes'
example.filters.arrayValues[stringKey].filter((item: string) => item !== 'choc') 
// ❌ Element implicitly has an 'any' type because expression of type '"milkshakes"' can't be used to index type 'string | { [key: string]: string[]; }'.
// ❌ Property 'milkshakes' does not exist on type 'string | { [key: string]: string[]; }'

example.filters.randomString = 'bye'
// ❌ Property 'randomString' does not exist on type '{ arrays: { [key: string]: string[]; }; } | { [key: string]: string; }'.
// ❌ Property 'randomString' does not exist on type '{ arrays: { [key: string]: string[]; }; }

Azt vártam, hogy a TypeScript megértse ezekben az objektumokban található típusokat, mivel a FiltersStateType-ban megadtam őket.

Tudod, miért történik ez?

Válasz #1

Ez a kiemelt Szakszervezet miatt történik:

export type FiltersStateType = {
  filters:
    | {
        arrayValues: {
          [key: string]: Array<string>
        }
      }
    | { [key: string]: string } // this one
// ---^^^^^^^^^^^^^^^^^^^^^^^^^---
}

Mivel a unióban megadtad a { [key: string]: string } típusát, az alábbi objektum érvényes:

const example: FiltersStateType = {
  filters: {
    arrayValues: 'hello',
  },
}

A TypeScript nem képes érvényesíteni az arrayValues kulcs értékének alakját, mivel a { [key: string]: string } maga azt jelenti, hogy bármelyik kulcsnak lehet string típusú értéke. Ideális esetben meg kellene változtatnod a típusdefinícióid szerkezetét valami ilyesmire:

// this is just an example, you should
// restructure as per your requirements 
type FiltersStateType = {
  filters: { [key: string]: string },
  arrayValues: { [key: string]: Array<string> }
}

Válasz #2

A FiltersStateType típusodat így deklarálhatod:

type FiltersStateType = {
  filters: {
    [key: string]: string | {[key: string]: string[]};
    arrayValues: { // can only appear once in filters object
      [key: string]: string[];
    }
  }
}

const example: FiltersStateType = {
  filters: {
    arrayValues: {
      sandwiches: ['ham', 'cheese'],
      milkshakes: ['choc', 'banana'],
    },
    randomString: 'hello',
  },
}

example.filters.arrayValues.sandwiches = example.filters.arrayValues.sandwiches.filter((item: string) => item !== 'ham');
console.log(example.filters.arrayValues.sandwiches);

const stringKey = 'milkshakes'
example.filters.arrayValues[stringKey] = example.filters.arrayValues[stringKey].filter((item: string) => item !== 'choc');
console.log(example.filters.arrayValues[stringKey]);

example.filters.randomString = 'bye';
console.log(example.filters.randomString);

Kapcsolódó cikkek